package net.hn.hnms.biz.plan.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import net.hn.hnms.biz.plan.domain.*;
import net.hn.hnms.biz.plan.easyexcel.IntegratedReportingListener;
import net.hn.hnms.biz.plan.enums.DataType;
import net.hn.hnms.biz.plan.enums.PlanDateType;
import net.hn.hnms.biz.plan.enums.WorkFaceType;
import net.hn.hnms.biz.plan.mapper.*;
import net.hn.hnms.biz.plan.request.ProductionMarketingCountReq;
import net.hn.hnms.biz.plan.request.SalesPlanReq;
import net.hn.hnms.biz.plan.service.ISaleDataAnalysisService;
import net.hn.hnms.biz.plan.service.IStatisticService;
import net.hn.hnms.biz.plan.utils.StatisticsUtil;
import net.hn.hnms.biz.plan.vo.*;
import net.hn.hnms.biz.plan.vo.energy.OtherMonthCostVo;
import net.hn.hnms.biz.plan.vo.energy.YearEnergyStatisticsVo;
import net.hn.hnms.sys.common.core.constant.Constants;
import net.hn.hnms.sys.common.core.domain.ResponsePage;
import net.hn.hnms.sys.common.core.exception.HuaNengException;
import net.hn.hnms.sys.common.core.utils.DateUtils;
import net.hn.hnms.sys.common.core.utils.StringUtils;
import net.hn.hnms.sys.common.mybatis.core.page.PageQuery;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static net.hn.hnms.biz.plan.group.service.impl.GroupServiceImp.sendGet;
import static net.hn.hnms.sys.common.core.utils.DateUtils.getMoMDateRange;

/**
 * @author ly
 * 生产统计服务层
 * @date 2022-08-26
 */
@Service
@DS("master")
@Slf4j
public class StatisticServiceImpl implements IStatisticService {


    private ExecutionFootageOutputMapper executionFootageOutputMapper;


    private ExecutionCostMapper executionCostMapper;

    private PlanOutputMapper planOutputMapper;

    private PlanDrivageMapper planDrivageMapper;

    private PlanWashingMapper planWashingMapper;

    private StatisticMapper statisticMapper;


    private ExecutionWashingMapper executionWashingMapper;

    @Autowired
    private YieldAnalysisMapper yieldAnalysisMapper;

    @Autowired
    private IntegratedReportingMapper integratedReportingMapper;

    @Autowired
    private ISaleDataAnalysisService saleDataAnalysisService;


    private static final String API_URL = "http://10.244.131.192:9000/";

    public StatisticServiceImpl(ExecutionFootageOutputMapper executionFootageOutputMapper, ExecutionCostMapper executionCostMapper,
                                PlanOutputMapper planOutputMapper, PlanDrivageMapper planDrivageMapper, PlanWashingMapper planWashingMapper,
                                StatisticMapper statisticMapper, ExecutionWashingMapper executionWashingMapper) {
        this.executionFootageOutputMapper = executionFootageOutputMapper;
        this.executionCostMapper = executionCostMapper;
        this.planOutputMapper = planOutputMapper;
        this.planDrivageMapper = planDrivageMapper;
        this.planWashingMapper = planWashingMapper;
        this.statisticMapper = statisticMapper;
        this.executionWashingMapper = executionWashingMapper;
    }

    /**
     * 生产统计-大屏
     *
     * @return ProduceStasticVO
     */
    @Override
    public ProduceStasticVO produceForBigScreen(String date, String mineCode) {
        Date now = DateUtil.offsetDay(new Date(), -1);
        if (StrUtil.isNotBlank(date)) {
            now = DateUtil.parseDate(date);
        }
        Date startDate = DateUtil.beginOfYear(now);
        Date endDate = DateUtil.endOfYear(startDate);
        //实际产出
        List<ExecutionFootageOutput> outputList = executionFootageOutputMapper.selectList(new LambdaQueryWrapper<ExecutionFootageOutput>()
                .ge(ExecutionFootageOutput::getExecutionDate, startDate)
                .eq(StrUtil.isNotBlank(mineCode), ExecutionFootageOutput::getMineCode, mineCode)
                .le(ExecutionFootageOutput::getExecutionDate, endDate));
        //实际洗选
        List<ExecutionWashing> washingList = executionWashingMapper.selectList(new LambdaQueryWrapper<ExecutionWashing>()
                .ge(ExecutionWashing::getExecutionDate, startDate)
                .eq(StrUtil.isNotBlank(mineCode), ExecutionWashing::getMineCode, mineCode)
                .le(ExecutionWashing::getExecutionDate, endDate));
        //计划产出
//        List<PlanOutput> planOutputList = planOutputMapper.selectList(new LambdaQueryWrapper<PlanOutput>()
//                .eq(PlanOutput::getOutputPlanType, PlanDateType.MONTH.getCode())
////                .eq(StrUtil.isNotBlank(mineCode), PlanOutput::getMineCode, mineCode)
//                .apply(" plan_start_date >= to_date('" + DateUtil.formatDate(startDate) + "','YYYY-MM-DD') ")
//                .apply(" plan_end_date <= to_date('" + DateUtil.formatDate(endDate) + "','YYYY-MM-DD') ")
//        );
        List<PlanOutput> planOutputList = planOutputMapper.selectList(new LambdaQueryWrapper<PlanOutput>()
                .eq(PlanOutput::getOutputPlanType, PlanDateType.YEAR.getCode())
                .eq(StrUtil.isNotBlank(mineCode), PlanOutput::getMineCode, mineCode)
                .apply(" plan_start_date >= to_date('" + DateUtil.formatDate(startDate) + "','YYYY-MM-DD') ")
                .apply(" plan_end_date <= to_date('" + DateUtil.formatDate(endDate) + "','YYYY-MM-DD') ")
        );

        //计划掘进
        List<PlanDrivage> planDrivageList = planDrivageMapper.selectList(new LambdaQueryWrapper<PlanDrivage>()
                .eq(PlanDrivage::getDrivagePlanType, PlanDateType.MONTH.getCode())
                .eq(StrUtil.isNotBlank(mineCode), PlanDrivage::getMineCode, mineCode)
                .apply(" plan_start_date >= to_date('" + DateUtil.formatDate(startDate) + "','YYYY-MM-DD') ")
                .apply(" plan_end_date <= to_date('" + DateUtil.formatDate(endDate) + "','YYYY-MM-DD') ")
        );
        //计划洗选
        List<PlanWashing> planWashingList = planWashingMapper.selectList(new LambdaQueryWrapper<PlanWashing>()
                .eq(PlanWashing::getWashingPlanType, PlanDateType.MONTH.getCode())
                .eq(StrUtil.isNotBlank(mineCode), PlanWashing::getMineCode, mineCode)
                .apply(" washing_plan_start_date >= to_date('" + DateUtil.formatDate(startDate) + "','YYYY-MM-DD') ")
                .apply(" washing_plan_end_date <= to_date('" + DateUtil.formatDate(endDate) + "','YYYY-MM-DD') ")
        );

        ProduceStasticVO produceStasticVO = new ProduceStasticVO();

        Date finalNow = now;

        //生产
        produceStasticVO.setProduceDay(
                BigDecimal.valueOf(outputList.parallelStream().filter(o -> o.getOutput() != null && o.getExecutionDate() != null
                        && DateUtil.isSameDay(o.getExecutionDate(), finalNow)).mapToDouble(o -> o.getOutput().doubleValue()).sum()).setScale(2, RoundingMode.CEILING)
        );

        produceStasticVO.setProduceMonth(
                BigDecimal.valueOf(outputList.parallelStream().filter(o -> o.getOutput() != null && o.getExecutionDate() != null
                        && DateUtil.isSameMonth(o.getExecutionDate(), finalNow)).mapToDouble(o -> o.getOutput().doubleValue()).sum()).divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP)
        );
        produceStasticVO.setProduceYear(
                BigDecimal.valueOf(outputList.parallelStream().filter(o -> o.getOutput() != null).mapToDouble(o -> o.getOutput().doubleValue()).sum()).divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP)
        );
        //计划产出
        BigDecimal planOutPutAll = BigDecimal.valueOf(planOutputList.parallelStream().filter(o -> o.getPlanOutput() != null).mapToDouble(o -> o.getPlanOutput().doubleValue()).sum()).divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP);
        produceStasticVO.setProducePercent(planOutPutAll.compareTo(Constants.ZERO) == 0 ? Constants.ZERO : produceStasticVO.getProduceYear().multiply(Constants.HUNDRED).divide(planOutPutAll, 2, RoundingMode.HALF_UP));


        //掘进
        produceStasticVO.setDrivageDay(BigDecimal.valueOf(outputList.parallelStream().filter(o -> StrUtil.equals(o.getWorkFaceType(), WorkFaceType.DRAVIGE.getCode()) && o.getFootage() != null && o.getExecutionDate() != null
                && DateUtil.isSameDay(o.getExecutionDate(), finalNow)).mapToDouble(o -> o.getFootage().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        produceStasticVO.setDrivageMonth(BigDecimal.valueOf(outputList.parallelStream().filter(o -> StrUtil.equals(o.getWorkFaceType(), WorkFaceType.DRAVIGE.getCode()) && o.getFootage() != null && o.getExecutionDate() != null
                && DateUtil.isSameMonth(o.getExecutionDate(), finalNow)).mapToDouble(o -> o.getFootage().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        produceStasticVO.setDrivageYear(BigDecimal.valueOf(outputList.parallelStream().filter(o -> StrUtil.equals(o.getWorkFaceType(), WorkFaceType.DRAVIGE.getCode()) && o.getFootage() != null && o.getExecutionDate() != null
        ).mapToDouble(o -> o.getFootage().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        //计划掘进
        BigDecimal planDrivageAll = BigDecimal.valueOf(planDrivageList.parallelStream().filter(o -> o.getDrivagePlanFootage() != null).mapToDouble(o -> o.getDrivagePlanFootage().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP);
        produceStasticVO.setDrivageePercent(planDrivageAll.compareTo(Constants.ZERO) == 0 ? Constants.ZERO : produceStasticVO.getDrivageYear().multiply(Constants.HUNDRED).divide(planDrivageAll, 2, RoundingMode.HALF_UP));


        //洗煤
        produceStasticVO.setWashingeDay(BigDecimal.valueOf(washingList.parallelStream().filter(o -> o.getWashingAmount() != null && o.getExecutionDate() != null
                && DateUtil.isSameDay(o.getExecutionDate(), finalNow)).mapToDouble(o -> o.getWashingAmount().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        produceStasticVO.setWashingeMonth(BigDecimal.valueOf(washingList.parallelStream().filter(o -> o.getWashingAmount() != null && o.getExecutionDate() != null
                        && DateUtil.isSameMonth(o.getExecutionDate(), finalNow)).mapToDouble(o -> o.getWashingAmount().doubleValue()).sum())
                .divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP));
        produceStasticVO.setWashingeYear(BigDecimal.valueOf(washingList.parallelStream().filter(o -> o.getWashingAmount() != null && o.getExecutionDate() != null)
                .mapToDouble(o -> o.getWashingAmount().doubleValue()).sum()).divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP));

        //计划洗选
        BigDecimal planWashingAll = BigDecimal.valueOf(planWashingList.parallelStream().filter(o -> o.getWashingPlanAmount() != null).mapToDouble(o -> o.getWashingPlanAmount().doubleValue()).sum()).divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP);
        produceStasticVO.setWashingePercent(planWashingAll.compareTo(Constants.ZERO) == 0 ? Constants.ZERO : produceStasticVO.getWashingeYear().multiply(Constants.HUNDRED).divide(planWashingAll, 2, RoundingMode.HALF_UP));
        produceStasticVO.setProduceAll(planOutPutAll);

        return produceStasticVO;
    }


    @Override
    public ProduceStasticVO gtyProduceForBigScreen(String date, String mineCode) {
        Date now = DateUtil.offsetDay(new Date(), -1);
        if (StrUtil.isNotBlank(date)) {
            now = DateUtil.parseDate(date);
        }
        Date startDate = DateUtil.beginOfYear(now);
        Date endDate = DateUtil.endOfYear(startDate);
        //实际产出
        List<ExecutionFootageOutput> outputList = executionFootageOutputMapper.selectList(new LambdaQueryWrapper<ExecutionFootageOutput>()
                .ge(ExecutionFootageOutput::getExecutionDate, startDate)
//                .eq(StrUtil.isNotBlank(mineCode), ExecutionFootageOutput::getMineCode, mineCode)
                .le(ExecutionFootageOutput::getExecutionDate, endDate));


        //实际洗选
        List<ExecutionWashing> washingList = executionWashingMapper.selectList(new LambdaQueryWrapper<ExecutionWashing>()
                .ge(ExecutionWashing::getExecutionDate, startDate)
//                .eq(StrUtil.isNotBlank(mineCode), ExecutionWashing::getMineCode, mineCode)
                .le(ExecutionWashing::getExecutionDate, endDate));
        //计划产出
//        List<PlanOutput> planOutputList = planOutputMapper.selectList(new LambdaQueryWrapper<PlanOutput>()
//                        .eq(PlanOutput::getOutputPlanType, PlanDateType.MONTH.getCode())
////                .eq(StrUtil.isNotBlank(mineCode), PlanOutput::getMineCode, mineCode)
//                        .apply(" plan_start_date >= to_date('" + DateUtil.formatDate(startDate) + "','YYYY-MM-DD') ")
//                        .apply(" plan_end_date <= to_date('" + DateUtil.formatDate(endDate) + "','YYYY-MM-DD') ")
//        );
        List<PlanOutput> planOutputList = planOutputMapper.selectList(new LambdaQueryWrapper<PlanOutput>()
                        .eq(PlanOutput::getOutputPlanType, PlanDateType.YEAR.getCode())
//                .eq(StrUtil.isNotBlank(mineCode), PlanOutput::getMineCode, mineCode)
                        .apply(" plan_start_date >= to_date('" + DateUtil.formatDate(startDate) + "','YYYY-MM-DD') ")
                        .apply(" plan_end_date <= to_date('" + DateUtil.formatDate(endDate) + "','YYYY-MM-DD') ")
        );
        //计划掘进
        List<PlanDrivage> planDrivageList = planDrivageMapper.selectList(new LambdaQueryWrapper<PlanDrivage>()
                        .eq(PlanDrivage::getDrivagePlanType, PlanDateType.MONTH.getCode())
//                .eq(StrUtil.isNotBlank(mineCode), PlanDrivage::getMineCode, mineCode)
                        .apply(" plan_start_date >= to_date('" + DateUtil.formatDate(startDate) + "','YYYY-MM-DD') ")
                        .apply(" plan_end_date <= to_date('" + DateUtil.formatDate(endDate) + "','YYYY-MM-DD') ")
        );
        //计划洗选
        List<PlanWashing> planWashingList = planWashingMapper.selectList(new LambdaQueryWrapper<PlanWashing>()
                        .eq(PlanWashing::getWashingPlanType, PlanDateType.MONTH.getCode())
//                .eq(StrUtil.isNotBlank(mineCode), PlanWashing::getMineCode, mineCode)
                        .apply(" washing_plan_start_date >= to_date('" + DateUtil.formatDate(startDate) + "','YYYY-MM-DD') ")
                        .apply(" washing_plan_end_date <= to_date('" + DateUtil.formatDate(endDate) + "','YYYY-MM-DD') ")
        );

        ProduceStasticVO produceStasticVO = new ProduceStasticVO();

        Date finalNow = now;

        //生产
        produceStasticVO.setProduceDay(
                BigDecimal.valueOf(outputList.parallelStream().filter(o -> o.getOutput() != null && o.getExecutionDate() != null
                        && DateUtil.isSameDay(o.getExecutionDate(), finalNow)).mapToDouble(o -> o.getOutput().doubleValue()).sum()).setScale(2, RoundingMode.CEILING)
        );

        produceStasticVO.setProduceMonth(
                BigDecimal.valueOf(outputList.parallelStream().filter(o -> o.getOutput() != null && o.getExecutionDate() != null
                        && DateUtil.isSameMonth(o.getExecutionDate(), finalNow)).mapToDouble(o -> o.getOutput().doubleValue()).sum()).divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP)
        );
        produceStasticVO.setProduceYear(
                BigDecimal.valueOf(outputList.parallelStream().filter(o -> o.getOutput() != null).mapToDouble(o -> o.getOutput().doubleValue()).sum()).divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP)
        );
        //计划产出
        BigDecimal planOutPutAll = BigDecimal.valueOf(planOutputList.parallelStream().filter(o -> o.getPlanOutput() != null).mapToDouble(o -> o.getPlanOutput().doubleValue()).sum()).divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP);
        produceStasticVO.setProducePercent(planOutPutAll.compareTo(Constants.ZERO) == 0 ? Constants.ZERO : produceStasticVO.getProduceYear().multiply(Constants.HUNDRED).divide(planOutPutAll, 2, RoundingMode.HALF_UP));


        //掘进
        produceStasticVO.setDrivageDay(BigDecimal.valueOf(outputList.parallelStream().filter(o -> StrUtil.equals(o.getWorkFaceType(), WorkFaceType.DRAVIGE.getCode()) && o.getFootage() != null && o.getExecutionDate() != null
                && DateUtil.isSameDay(o.getExecutionDate(), finalNow)).mapToDouble(o -> o.getFootage().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        produceStasticVO.setDrivageMonth(BigDecimal.valueOf(outputList.parallelStream().filter(o -> StrUtil.equals(o.getWorkFaceType(), WorkFaceType.DRAVIGE.getCode()) && o.getFootage() != null && o.getExecutionDate() != null
                && DateUtil.isSameMonth(o.getExecutionDate(), finalNow)).mapToDouble(o -> o.getFootage().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        produceStasticVO.setDrivageYear(BigDecimal.valueOf(outputList.parallelStream().filter(o -> StrUtil.equals(o.getWorkFaceType(), WorkFaceType.DRAVIGE.getCode()) && o.getFootage() != null && o.getExecutionDate() != null
        ).mapToDouble(o -> o.getFootage().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        //计划掘进
        BigDecimal planDrivageAll = BigDecimal.valueOf(planDrivageList.parallelStream().filter(o -> o.getDrivagePlanFootage() != null).mapToDouble(o -> o.getDrivagePlanFootage().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP);
        produceStasticVO.setDrivageePercent(planDrivageAll.compareTo(Constants.ZERO) == 0 ? Constants.ZERO : produceStasticVO.getDrivageYear().multiply(Constants.HUNDRED).divide(planDrivageAll, 2, RoundingMode.HALF_UP));


        //洗煤
        produceStasticVO.setWashingeDay(BigDecimal.valueOf(washingList.parallelStream().filter(o -> o.getWashingAmount() != null && o.getExecutionDate() != null
                && DateUtil.isSameDay(o.getExecutionDate(), finalNow)).mapToDouble(o -> o.getWashingAmount().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        produceStasticVO.setWashingeMonth(BigDecimal.valueOf(washingList.parallelStream().filter(o -> o.getWashingAmount() != null && o.getExecutionDate() != null
                        && DateUtil.isSameMonth(o.getExecutionDate(), finalNow)).mapToDouble(o -> o.getWashingAmount().doubleValue()).sum())
                .divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP));
        produceStasticVO.setWashingeYear(BigDecimal.valueOf(washingList.parallelStream().filter(o -> o.getWashingAmount() != null && o.getExecutionDate() != null)
                .mapToDouble(o -> o.getWashingAmount().doubleValue()).sum()).divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP));

        //计划洗选
        BigDecimal planWashingAll = BigDecimal.valueOf(planWashingList.parallelStream().filter(o -> o.getWashingPlanAmount() != null).mapToDouble(o -> o.getWashingPlanAmount().doubleValue()).sum()).divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP);
        produceStasticVO.setWashingePercent(planWashingAll.compareTo(Constants.ZERO) == 0 ? Constants.ZERO : produceStasticVO.getWashingeYear().multiply(Constants.HUNDRED).divide(planWashingAll, 2, RoundingMode.HALF_UP));
        produceStasticVO.setProduceAll(planOutPutAll);
        return produceStasticVO;
    }

    @Override
    public MonthYieldVo yieldByMonth(String mineCode) {
        MonthYieldVo vo = new MonthYieldVo();
        //计划产量
        BigDecimal monthOutput = new BigDecimal("0");
        Map<String, Object> monthOutputMap = planOutputMapper.getPlanMonthOutput(mineCode);
        if (monthOutputMap != null && !monthOutputMap.isEmpty())
            monthOutput = monthOutputMap.get("planoutput") == null ? new BigDecimal("0") : new BigDecimal(monthOutputMap.get("planoutput").toString());
        if (!(monthOutput.compareTo(BigDecimal.ZERO) == 0))
            monthOutput = monthOutput.divide(new BigDecimal("10000"), BigDecimal.ROUND_HALF_UP);
        vo.setPlanOutput(monthOutput);
        //累计产量
        BigDecimal sumOutput = new BigDecimal("0");
        Map<String, Object> sumOutputMap = planOutputMapper.getSumMonthOutput(mineCode);
        if (sumOutputMap != null && !sumOutputMap.isEmpty())
            sumOutput = sumOutputMap.get("sum") == null ? new BigDecimal("0") : new BigDecimal(sumOutputMap.get("sum").toString());
        if (!(sumOutput.compareTo(BigDecimal.ZERO) == 0))
            sumOutput = sumOutput.divide(new BigDecimal("10000"), BigDecimal.ROUND_HALF_UP);
        vo.setOutput(sumOutput);
        //计算完成率
        BigDecimal completionRate = new BigDecimal("0");
        if (!(monthOutput.compareTo(BigDecimal.ZERO) == 0) && !(sumOutput.compareTo(BigDecimal.ZERO) == 0))
            completionRate = sumOutput.divide(monthOutput, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
        vo.setCompletionRate(completionRate);
        Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:OO"));
        int day = c.get(Calendar.DAY_OF_MONTH);    //获取当前天数
        int first = c.getActualMinimum(c.DAY_OF_MONTH);    //获取本月最小天数
        int last = c.getActualMaximum(c.DAY_OF_MONTH);    //获取本月最大天数
        int newFirst = day - first;
        int newLast = last - day;
        vo.setNowDate(day);
        vo.setPastDate(newFirst);
        vo.setSurplusDate(newLast);
        return vo;
    }

    @Override
    public YearYieldVo yieldByYear(String mineCode) {
        YearYieldVo vo = new YearYieldVo();
        //计划产量
        BigDecimal planOutput = new BigDecimal("0");
//        Map<String, Object> planOutputMap = planOutputMapper.getPlanYearOutput(mineCode);
//        if (planOutputMap != null && !planOutputMap.isEmpty())
//            planOutput = planOutputMap.get("planoutput") == null ? new BigDecimal("0") : new BigDecimal(planOutputMap.get("planoutput").toString());
//        if (!(planOutput.compareTo(BigDecimal.ZERO) == 0))
//            planOutput = planOutput.divide(new BigDecimal("10000"), BigDecimal.ROUND_CEILING);
//

        Date now = DateUtil.offsetDay(new Date(), -1);
        Date startDate = DateUtil.beginOfYear(now);
        Date endDate = DateUtil.endOfYear(startDate);
        List<PlanOutput> planOutputList = planOutputMapper.selectList(new LambdaQueryWrapper<PlanOutput>()
                        .eq(PlanOutput::getOutputPlanType, PlanDateType.YEAR.getCode())
//                .eq(StrUtil.isNotBlank(mineCode), PlanOutput::getMineCode, mineCode)
                        .apply(" plan_start_date >= to_date('" + DateUtil.formatDate(startDate) + "','YYYY-MM-DD') ")
                        .apply(" plan_end_date <= to_date('" + DateUtil.formatDate(endDate) + "','YYYY-MM-DD') ")
        );

        BigDecimal planOutPutAll = BigDecimal.valueOf(planOutputList.parallelStream().filter(o -> o.getPlanOutput() != null).mapToDouble(o -> o.getPlanOutput().doubleValue()).sum()).divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP);
        planOutput = planOutPutAll;
        vo.setPlanOutput(planOutPutAll);
        //累计产量
        BigDecimal output = new BigDecimal("0");
        Map<String, Object> outputMap = planOutputMapper.getSumYearOutput(mineCode);
        if (outputMap != null && !outputMap.isEmpty())
            output = outputMap.get("sum") == null ? new BigDecimal("0") : new BigDecimal(outputMap.get("sum").toString());
        if (!(output.compareTo(BigDecimal.ZERO) == 0))
            output = output.divide(new BigDecimal("10000"), BigDecimal.ROUND_CEILING);
        vo.setOutput(output);
        //计算完成率
        BigDecimal completionRate = new BigDecimal("0");
        if (!(planOutput.compareTo(BigDecimal.ZERO) == 0) && !(output.compareTo(BigDecimal.ZERO) == 0))
            completionRate = output.divide(planOutput, BigDecimal.ROUND_CEILING).multiply(new BigDecimal("100"));
        vo.setCompletionRate(completionRate);
        //核定产能
        BigDecimal capacity = new BigDecimal("480");
        vo.setCapacity(capacity);
        return vo;
    }

    @Autowired
    private DimDrivageFaceMapper dimDrivageFaceMapper;

    @Override
    public CompletionRateVo completionRate(String mineCode, String planDrivageName) {

        String drivageId = getDrivageId(mineCode, planDrivageName);

        CompletionRateVo vo = new CompletionRateVo();
        //回采进尺计划
        BigDecimal miningPlanFootage = new BigDecimal("0");
        Map<String, Object> miningPlanFootageMap = planOutputMapper.getMiningPlanFootage(0, mineCode);
        if (miningPlanFootageMap != null && !miningPlanFootageMap.isEmpty())
            miningPlanFootage = miningPlanFootageMap.get("miningplanfootage") == null ? new BigDecimal("0") : new BigDecimal(miningPlanFootageMap.get("miningplanfootage").toString());
        vo.setMiningPlanFootage(miningPlanFootage);
        //掘进计划进尺
        BigDecimal drivagePlanFootage = new BigDecimal("0");
        Map<String, Object> drivagePlanFootageMap = planOutputMapper.getDrivagePlanFootage(0, mineCode, drivageId);
        if (drivagePlanFootageMap != null && !drivagePlanFootageMap.isEmpty())
            drivagePlanFootage = drivagePlanFootageMap.get("drivageplanfootage") == null ? new BigDecimal("0") : new BigDecimal(drivagePlanFootageMap.get("drivageplanfootage").toString());
        vo.setDrivagePlanFootage(drivagePlanFootage);
        //回采进尺完成
        BigDecimal miningFootage = new BigDecimal("0");
        Map<String, Object> miningFootageMap = planOutputMapper.getFootageByType("0", 0, mineCode, null);
        if (miningFootageMap != null && !miningFootageMap.isEmpty())
            miningFootage = miningFootageMap.get("sumfootage") == null ? new BigDecimal("0") : new BigDecimal(miningFootageMap.get("sumfootage").toString());
        vo.setMiningFootage(miningFootage);
        //掘进进尺完成
        BigDecimal drivageFootage = new BigDecimal("0");
        Map<String, Object> drivageFootageMap = planOutputMapper.getFootageByType("1", 0, mineCode, drivageId);
        if (drivageFootageMap != null && !drivageFootageMap.isEmpty())
            drivageFootage = drivageFootageMap.get("sumfootage") == null ? new BigDecimal("0") : new BigDecimal(drivageFootageMap.get("sumfootage").toString());
        vo.setDrivageFootage(drivageFootage);
        //回采进尺完成率
        BigDecimal miningCompletionRate = new BigDecimal("0");
        if (!(miningFootage.compareTo(BigDecimal.ZERO) == 0) && !(miningPlanFootage.compareTo(BigDecimal.ZERO) == 0))
            miningCompletionRate = miningFootage.divide(miningPlanFootage, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
        vo.setMiningCompletionRate(miningCompletionRate);
        //掘进进尺完成率
        BigDecimal drivageCompletionRate = new BigDecimal("0");
        if (!(drivageFootage.compareTo(BigDecimal.ZERO) == 0) && !(drivagePlanFootage.compareTo(BigDecimal.ZERO) == 0))
            drivageCompletionRate = drivageFootage.divide(drivagePlanFootage, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
        vo.setDrivageCompletionRate(drivageCompletionRate);
        //月产量完成情况
        //计划产量
        BigDecimal monthOutput = new BigDecimal("0");
        Map<String, Object> monthOutputMap = planOutputMapper.getPlanMonthOutput(mineCode);
        if (monthOutputMap != null && !monthOutputMap.isEmpty())
            monthOutput = monthOutputMap.get("planoutput") == null ? new BigDecimal("0") : new BigDecimal(monthOutputMap.get("planoutput").toString());
        if (!(monthOutput.compareTo(BigDecimal.ZERO) == 0))
            monthOutput = monthOutput.divide(new BigDecimal("10000"), BigDecimal.ROUND_HALF_UP);
        vo.setPlanOutput(monthOutput);
        //累计产量
        BigDecimal sumOutput = new BigDecimal("0");
        Map<String, Object> sumOutputMap = planOutputMapper.getSumMonthOutput(mineCode);
        if (sumOutputMap != null && !sumOutputMap.isEmpty())
            sumOutput = sumOutputMap.get("sum") == null ? new BigDecimal("0") : new BigDecimal(sumOutputMap.get("sum").toString());
        if (!(sumOutput.compareTo(BigDecimal.ZERO) == 0))
            sumOutput = sumOutput.divide(new BigDecimal("10000"), BigDecimal.ROUND_HALF_UP);
        vo.setOutput(sumOutput);
        //计算完成率
        BigDecimal completionRate = new BigDecimal("0");
        if (!(monthOutput.compareTo(BigDecimal.ZERO) == 0) && !(sumOutput.compareTo(BigDecimal.ZERO) == 0))
            completionRate = sumOutput.divide(monthOutput, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
        vo.setCompletionRate(completionRate);
        return vo;
    }


    public Map<String, BigDecimal> getDrivagefootage(String mineCode, String planDrivageName) {

        String drivageId = getDrivageId(mineCode, planDrivageName);
        Map<String, BigDecimal> map = new HashMap<>();
        BigDecimal drivageFootage = new BigDecimal("0");
        if (StringUtils.isBlank(drivageId)) {
            map.put("drivageFootage", drivageFootage);
            return map;
        }

        //掘进进尺完成

        Map<String, Object> drivageFootageMap = planOutputMapper.getFootageByType("1", 2, mineCode, drivageId);
        if (drivageFootageMap != null && !drivageFootageMap.isEmpty())
            drivageFootage = drivageFootageMap.get("sumfootage") == null ? new BigDecimal("0") : new BigDecimal(drivageFootageMap.get("sumfootage").toString());

        map.put("drivageFootage", drivageFootage);
        return map;
    }

    public String getDrivageId(String mineCode, String planDrivageName) {
        String drivageId = null;
        if (StringUtils.isNotBlank(planDrivageName)) {
            DynamicDataSourceContextHolder.push("slave");
            List<DimDrivageFaceVO> drivageList = dimDrivageFaceMapper.getDrivageByMineCodeAndDrivageName(mineCode, planDrivageName);
            drivageId = drivageList == null || drivageList.size() == 0 ? null : drivageList.get(0).getDrivageFaceId();
//            DrivageList.stream().forEach(drivage->{
//                System.out.println(drivage);
//            });

            DynamicDataSourceContextHolder.clear();
        }
        return drivageId;
    }

    @Override
    public CompletionRateVo completionRateByYear(String mineCode, String planDrivageName) {

        String drivageId = getDrivageId(mineCode, planDrivageName);

        CompletionRateVo vo = new CompletionRateVo();
        //回采进尺计划
        BigDecimal miningPlanFootage = new BigDecimal("0");
        Map<String, Object> miningPlanFootageMap = planOutputMapper.getMiningPlanFootage(1, mineCode);
        if (miningPlanFootageMap != null && !miningPlanFootageMap.isEmpty())
            miningPlanFootage = miningPlanFootageMap.get("miningplanfootage") == null ? new BigDecimal("0") : new BigDecimal(miningPlanFootageMap.get("miningplanfootage").toString());
        vo.setMiningPlanFootage(miningPlanFootage);
        //掘进计划进尺
        BigDecimal drivagePlanFootage = new BigDecimal("0");
        Map<String, Object> drivagePlanFootageMap = planOutputMapper.getDrivagePlanFootage(1, mineCode, drivageId);
        if (drivagePlanFootageMap != null && !drivagePlanFootageMap.isEmpty())
            drivagePlanFootage = drivagePlanFootageMap.get("drivageplanfootage") == null ? new BigDecimal("0") : new BigDecimal(drivagePlanFootageMap.get("drivageplanfootage").toString());
        vo.setDrivagePlanFootage(drivagePlanFootage);
        //回采进尺完成
        BigDecimal miningFootage = new BigDecimal("0");
        Map<String, Object> miningFootageMap = planOutputMapper.getFootageByType("0", 1, mineCode, null);
        if (miningFootageMap != null && !miningFootageMap.isEmpty())
            miningFootage = miningFootageMap.get("sumfootage") == null ? new BigDecimal("0") : new BigDecimal(miningFootageMap.get("sumfootage").toString());
        vo.setMiningFootage(miningFootage);
        //掘金进尺完成
        BigDecimal drivageFootage = new BigDecimal("0");
        Map<String, Object> drivageFootageMap = planOutputMapper.getFootageByType("1", 1, mineCode, drivageId);
        if (drivageFootageMap != null && !drivageFootageMap.isEmpty())
            drivageFootage = drivageFootageMap.get("sumfootage") == null ? new BigDecimal("0") : new BigDecimal(drivageFootageMap.get("sumfootage").toString());
        vo.setDrivageFootage(drivageFootage);
        //回采进尺完成率
        BigDecimal miningCompletionRate = new BigDecimal("0");
        if (!(miningFootage.compareTo(BigDecimal.ZERO) == 0) && !(miningPlanFootage.compareTo(BigDecimal.ZERO) == 0))
            miningCompletionRate = miningFootage.divide(miningPlanFootage, BigDecimal.ROUND_CEILING).multiply(new BigDecimal("100"));
        vo.setMiningCompletionRate(miningCompletionRate);
        //掘进进尺完成率
        BigDecimal drivageCompletionRate = new BigDecimal("0");
        if (!(drivageFootage.compareTo(BigDecimal.ZERO) == 0) && !(drivagePlanFootage.compareTo(BigDecimal.ZERO) == 0))
            drivageCompletionRate = drivageFootage.divide(drivagePlanFootage, BigDecimal.ROUND_CEILING).multiply(new BigDecimal("100"));
        vo.setDrivageCompletionRate(drivageCompletionRate);
        //巷道维修计划(m)
        BigDecimal planRepair = new BigDecimal("0");
        //材料消耗计划(万元)
        BigDecimal planMaterial = new BigDecimal("0");
        Map<String, Object> planRepairMap = planOutputMapper.getPlanRepair(1, mineCode);
        if (planRepairMap != null && !planRepairMap.isEmpty()) {
            planRepair = planRepairMap.get("planrepair") == null ? new BigDecimal("0") : new BigDecimal(planRepairMap.get("planrepair").toString());
            planMaterial = planRepairMap.get("planmaterial") == null ? new BigDecimal("0") : new BigDecimal(planRepairMap.get("planmaterial").toString());
        }
        vo.setPlanRepair(planRepair);
        vo.setPlanMaterial(planMaterial);
        //巷道维修(m)
        BigDecimal repair = new BigDecimal("0");
        Map<String, Object> repairMap = planOutputMapper.getRepair(1, mineCode);
        if (repairMap != null && !repairMap.isEmpty()) {
            repair = repairMap.get("repair") == null ? new BigDecimal("0") : new BigDecimal(repairMap.get("repair").toString());
        }
        vo.setRepair(repair);
        //材料消耗(万元)
        BigDecimal costMaterial = new BigDecimal("0");
        Map<String, Object> costMaterialMap = planOutputMapper.getCostMaterial(1, mineCode);
        if (costMaterialMap != null && !costMaterialMap.isEmpty()) {
            costMaterial = costMaterialMap.get("costmaterial") == null ? new BigDecimal("0") : new BigDecimal(costMaterialMap.get("costmaterial").toString());
        }
        vo.setCostMaterial(costMaterial);
        //巷道维修完成率
        BigDecimal repairRate = new BigDecimal("0");
        if (!(planRepair.compareTo(BigDecimal.ZERO) == 0) && !(repair.compareTo(BigDecimal.ZERO) == 0))
            repairRate = repair.divide(planRepair, BigDecimal.ROUND_CEILING).multiply(new BigDecimal("100"));
        vo.setRepairRate(repairRate);
        //材料消耗计划完成率
        BigDecimal costMaterialRate = new BigDecimal("0");
        if (!(planMaterial.compareTo(BigDecimal.ZERO) == 0) && !(costMaterial.compareTo(BigDecimal.ZERO) == 0))
            costMaterialRate = costMaterial.divide(planMaterial, BigDecimal.ROUND_CEILING).multiply(new BigDecimal("100"));
        vo.setCostMaterialRate(costMaterialRate);

        //年度计划完成情况
        //计划产量
        BigDecimal planOutput = new BigDecimal("0");
//        Map<String, Object> planOutputMap = planOutputMapper.getPlanYearOutput(mineCode);
//        if (planOutputMap != null && !planOutputMap.isEmpty())
//            planOutput = planOutputMap.get("planoutput") == null ? new BigDecimal("0") : new BigDecimal(planOutputMap.get("planoutput").toString());
//        if (!(planOutput.compareTo(BigDecimal.ZERO) == 0))
//            planOutput = planOutput.divide(new BigDecimal("10000"), BigDecimal.ROUND_CEILING);

        Date now = DateUtil.offsetDay(new Date(), -1);
        Date startDate = DateUtil.beginOfYear(now);
        Date endDate = DateUtil.endOfYear(startDate);
        List<PlanOutput> planOutputList = planOutputMapper.selectList(new LambdaQueryWrapper<PlanOutput>()
                        .eq(PlanOutput::getOutputPlanType, PlanDateType.YEAR.getCode())
//                .eq(StrUtil.isNotBlank(mineCode), PlanOutput::getMineCode, mineCode)
                        .apply(" plan_start_date >= to_date('" + DateUtil.formatDate(startDate) + "','YYYY-MM-DD') ")
                        .apply(" plan_end_date <= to_date('" + DateUtil.formatDate(endDate) + "','YYYY-MM-DD') ")
        );

        BigDecimal planOutPutAll = BigDecimal.valueOf(planOutputList.parallelStream().filter(o -> o.getPlanOutput() != null).mapToDouble(o -> o.getPlanOutput().doubleValue()).sum()).divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP);
        planOutput = planOutPutAll;
        vo.setPlanOutput(planOutPutAll);
        //累计产量
        BigDecimal output = new BigDecimal("0");
        Map<String, Object> outputMap = planOutputMapper.getSumYearOutput(mineCode);
        if (outputMap != null && !outputMap.isEmpty())
            output = outputMap.get("sum") == null ? new BigDecimal("0") : new BigDecimal(outputMap.get("sum").toString());
        if (!(output.compareTo(BigDecimal.ZERO) == 0))
            output = output.divide(new BigDecimal("10000"), BigDecimal.ROUND_CEILING);
        vo.setOutput(output);
        //计算完成率
        BigDecimal completionRate = new BigDecimal("0");
        if (!(planOutput.compareTo(BigDecimal.ZERO) == 0) && !(output.compareTo(BigDecimal.ZERO) == 0))
            completionRate = output.divide(planOutput, BigDecimal.ROUND_CEILING).multiply(new BigDecimal("100"));
        vo.setCompletionRate(completionRate);
        return vo;

    }

    @Override
    public List<PlanCurveVo> outputCurve(String mineCode) {
        List<PlanCurveVo> result = new ArrayList<>();
        List<Map<String, Object>> outPutCurvelist = planOutputMapper.getOutputCurve(mineCode);
        List<Map<String, Object>> planOutputCurveList = planOutputMapper.getPlanOutputCurve(mineCode);
        List<Map<String, Object>> monthList = planOutputMapper.getMonth();
        int i = 0;
        for (Map<String, Object> Map : monthList) {
            String month = Map.get("month") == null ? "" : Map.get("month").toString();
            PlanCurveVo vo = new PlanCurveVo();
            //月产量
//            if(outPutCurvelist.size() > i){
            for (Map<String, Object> outPutCurveMap : outPutCurvelist) {
                String output = outPutCurveMap.get("output") == null ? "0" : outPutCurveMap.get("output").toString();
                String monthDate = outPutCurveMap.get("monthdate") == null ? "" : outPutCurveMap.get("monthdate").toString();
                if (!monthDate.equals("") && null != monthDate && month.equals(monthDate)) {
                    BigDecimal newOutPut = new BigDecimal(output);
                    newOutPut = newOutPut.divide(new BigDecimal("10000"), BigDecimal.ROUND_CEILING);
                    vo.setOutput(newOutPut);
                    break;
                }
            }
//            }
            //计划月产量
//            if(planOutputCurveList.size() > i){
            for (Map<String, Object> planOutputCurveMap : planOutputCurveList) {
                String planoutput = planOutputCurveMap.get("planoutput") == null ? "0" : planOutputCurveMap.get("planoutput").toString();
                String monthDate = planOutputCurveMap.get("monthdate") == null ? "" : planOutputCurveMap.get("monthdate").toString();
                if (!monthDate.equals("") && null != monthDate && month.equals(monthDate)) {
                    BigDecimal newPlanoutput = new BigDecimal(planoutput);
                    newPlanoutput = newPlanoutput.divide(new BigDecimal("10000"), BigDecimal.ROUND_CEILING);
                    vo.setPlanoutput(newPlanoutput);
                    break;
                }
            }
//            }
            vo.setMonthDate(month);
//            i++;
            result.add(vo);
        }
        return result;
    }

    @Override
    public List<Map<String, Object>> planOutputCurve(String mineCode) {
        return planOutputMapper.getPlanOutputCurve(mineCode);
    }

    /**
     * 经营综合概览-生成计划统计
     *
     * @param month 月份
     * @return 各计划完成情况
     */
    @Override
    public Map<String, PlanStatisticVO> planComplete(Integer month, String mineCode) {
        //获得起始日期
        Date[] dateRange = DateUtils.getDateRange(null, month);

        PlanCompleteStatisticVO completeInfo = statisticMapper.planComplete(dateRange[0], dateRange[1], mineCode);
        Map<String, PlanStatisticVO> result = new HashMap<>();
        result.put(DataType.DEVELOP.name(), createPlanComplete(DataType.DEVELOP, completeInfo.getPlanDevelopment(), completeInfo.getDevelopment()));
        result.put(DataType.DRIVAGE.name(), createPlanComplete(DataType.DRIVAGE, completeInfo.getPlanDrivage(), completeInfo.getDrivage()));
        result.put(DataType.MINING.name(), createPlanComplete(DataType.MINING, completeInfo.getPlanMining(), completeInfo.getMining()));
        result.put(DataType.OUTPUT.name(), createPlanComplete(DataType.OUTPUT, completeInfo.getPlanOutput().divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP), completeInfo.getOutput().divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP)));
        result.put(DataType.WASHING.name(), createPlanComplete(DataType.WASHING, completeInfo.getPlanWashing().divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP), completeInfo.getWashing().divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP)));
        return result;
    }

    /**
     * 公司端-生成计划统计
     *
     * @param month    月份
     * @param mineCode
     * @return 各计划完成情况
     */
    @Override
    public Map<String, PlanStatisticVO> planComplete2(Integer month, String mineCode) {
        //获得起始日期
        Date[] dateRange = DateUtils.getDateRange(null, month);

        PlanCompleteStatisticVO completeInfo = statisticMapper.planComplete2(dateRange[0], dateRange[1], mineCode);
        Map<String, PlanStatisticVO> result = new HashMap<>();
        result.put(DataType.DEVELOP.name(), createPlanComplete(DataType.DEVELOP, completeInfo.getPlanDevelopment(), completeInfo.getDevelopment()));
        result.put(DataType.DRIVAGE.name(), createPlanComplete(DataType.DRIVAGE, completeInfo.getPlanDrivage(), completeInfo.getDrivage()));
        result.put(DataType.MINING.name(), createPlanComplete(DataType.MINING, completeInfo.getPlanMining(), completeInfo.getMining()));
        result.put(DataType.SALE.name(), createPlanComplete(DataType.SALE, completeInfo.getPlanOutput().divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING), completeInfo.getOutput().divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING)));
        //result.put(DataType.SALE.name(), createPlanComplete(DataType.SALE, completeInfo.getPlanOutput(), completeInfo.getOutput()));
        result.put(DataType.WASHING.name(), createPlanComplete(DataType.WASHING, completeInfo.getPlanWashing().divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING), completeInfo.getWashing().divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING)));
        return result;
    }

    /**
     * 经营综合概览-其他生产计划
     *
     * @param month 月份
     * @return 其他计划完成情况
     */
    @Override
    public Map<String, PlanStatisticVO> planOther(Integer month, String mineCode) {
        //获得起始日期
        Date[] dateRange = DateUtils.getDateRange(null, month);
        PlanOtherStatisticVO completeInfo = statisticMapper.planOther(dateRange[0], dateRange[1], mineCode);
        Map<String, PlanStatisticVO> result = new HashMap<>();
        result.put(DataType.REPAIR.name(), createPlanComplete(DataType.REPAIR, completeInfo.getPlanRepair(), completeInfo.getRepair(), 0, RoundingMode.CEILING));
        result.put(DataType.GROUT.name(), createPlanComplete(DataType.GROUT, completeInfo.getPlanGrout(), completeInfo.getGrout(), 0, RoundingMode.CEILING));
        result.put(DataType.NITROGEN.name(), createPlanComplete(DataType.NITROGEN, completeInfo.getPlanNitrogen(), completeInfo.getNitrogen(), 0, RoundingMode.CEILING));
        result.put(DataType.GASEXT.name(), createPlanComplete(DataType.GASEXT, completeInfo.getPlanGasext(), completeInfo.getGasext(), 0, RoundingMode.CEILING));
        result.put(DataType.MATERIAL.name(), createPlanComplete(DataType.MATERIAL, completeInfo.getPlanMaterial(), completeInfo.getMaterial(), 0, RoundingMode.CEILING));
        result.put(DataType.RECYCLE.name(), createPlanComplete(DataType.RECYCLE, completeInfo.getPlanRecycle(), completeInfo.getRecycle(), 0, RoundingMode.CEILING));

        //水电
        DynamicDataSourceContextHolder.push("energy");
        MonthValue waterAndElectricity = statisticMapper.costWaterAndElectricity(dateRange[0], dateRange[1], mineCode);
        DynamicDataSourceContextHolder.clear();
        waterAndElectricity = waterAndElectricity == null ? new MonthValue() : waterAndElectricity;


        PlanOtherStatisticVO planOtherStatisticVO = statisticMapper.planOtherPower(dateRange[0], dateRange[1], mineCode);
        waterAndElectricity.setTotal2(planOtherStatisticVO != null ? planOtherStatisticVO.getPower().multiply(new BigDecimal("10000")) : new BigDecimal("0"));

        PlanStatisticVO water = new PlanStatisticVO();
        water.setDataCode(DataType.WATER.name());
        water.setDataName(DataType.WATER.getDesc());
        water.setPlanTotal(completeInfo.getPlanWater().setScale(0, RoundingMode.HALF_UP));//计划
        water.setCompleteTotal(completeInfo.getWater().setScale(2, RoundingMode.HALF_UP));//执行
        water.setPercent(water.getPlanTotal().compareTo(BigDecimal.ZERO) == 0 ? Constants.ZERO : water.getCompleteTotal().multiply(Constants.HUNDRED).divide(water.getPlanTotal(), 0, RoundingMode.CEILING));
        result.put(DataType.WATER.name(), water);

        PlanStatisticVO power = new PlanStatisticVO();
        power.setDataCode(DataType.POWER.name());
        power.setDataName(DataType.POWER.getDesc());
        power.setPlanTotal(completeInfo.getPlanPower().setScale(0, RoundingMode.CEILING));
        power.setCompleteTotal(waterAndElectricity.getTotal2().divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING));
        power.setPercent(power.getPlanTotal().compareTo(BigDecimal.ZERO) == 0 ? Constants.ZERO : power.getCompleteTotal().multiply(Constants.HUNDRED).divide(power.getPlanTotal(), 0, RoundingMode.CEILING));
        result.put(DataType.POWER.name(), power);
        return result;
    }

    /**
     * 构建对象
     *
     * @param dataType 计划类型
     * @param plan     计划量
     * @param complete 完成量
     * @return 数据统计结果
     */
    private PlanStatisticVO createPlanComplete(DataType dataType, BigDecimal plan, BigDecimal complete, int scale, RoundingMode mode) {
        PlanStatisticVO vo = new PlanStatisticVO();
        vo.setDataCode(dataType.name());
        vo.setDataName(dataType.getDesc());
        vo.setPlanTotal(plan.setScale(scale, mode));
        vo.setCompleteTotal(complete.setScale(scale, mode));
        vo.setPercent(vo.getPlanTotal().compareTo(BigDecimal.ZERO) == 0 ? Constants.ZERO : vo.getCompleteTotal().multiply(Constants.HUNDRED).divide(vo.getPlanTotal(), scale, mode));
        return vo;
    }

    /**
     * 构建对象
     *
     * @param dataType 计划类型
     * @param plan     计划量
     * @param complete 完成量
     * @return 数据统计结果
     */
    private PlanStatisticVO createPlanComplete(DataType dataType, BigDecimal plan, BigDecimal complete) {
        return createPlanComplete(dataType, plan, complete, 2, RoundingMode.CEILING);
    }

    /**
     * @param month
     * @return
     */
    @Override
    public ExecutionInfoVO otherActual(Integer month, String mineCode) {
        Date[] dateRange = DateUtils.getDateRange(null, month);
        ExecutionInfoVO vo = new ExecutionInfoVO();

        DynamicDataSourceContextHolder.push("shipped");
        List<MonthValue> sales = statisticMapper.realSaleOfMonth(dateRange[0], dateRange[1], mineCode);
        DynamicDataSourceContextHolder.clear();

        vo.setSaleRevenue(BigDecimal.valueOf(sales.stream().mapToDouble(o -> o.getTotal2().doubleValue()).sum()).divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING));
        vo.setRevenue(vo.getSaleRevenue().add(vo.getPackageRevenue()).add(vo.getSubRoadRevenue()));

        //水电
        DynamicDataSourceContextHolder.push("energy");
        MonthValue waterAndElectricity = statisticMapper.costWaterAndElectricity(dateRange[0], dateRange[1], mineCode);
        DynamicDataSourceContextHolder.clear();
        waterAndElectricity = waterAndElectricity == null ? new MonthValue() : waterAndElectricity;
//        vo.setOtherCost(result.get(0));
//        vo.setOilCost(result.get(1));
//        vo.setGasCost(result.get(2));
        vo.setWaterCost(waterAndElectricity.getTotal().divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING));
        vo.setPowerCost(waterAndElectricity.getTotal2().divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING));

        vo.setCost(vo.getOtherCost().add(vo.getOilCost()).add(vo.getGasCost()).add(vo.getWaterCost()).add(vo.getPowerCost()));

        return vo;
    }

    /**
     * 经营综合概览-经营状况
     *
     * @param month 月份
     * @return WeggVO
     */
    @Override
    public WeggVO wegg(Integer month, String mineCode) {
        //TODO 假数据需要修改
        WeggVO vo = new WeggVO();
        Map<Integer, List<BigDecimal>> fakeMap = new HashMap<>();
        int monthNumber = DateUtil.month(new Date()) + 1;
        for (int i = 1; i < monthNumber + 1; i++) {
            List<BigDecimal> list = new ArrayList<>(8);
            list.add(BigDecimal.valueOf((monthNumber / 6) * monthNumber * 5 * 1.8).setScale(2, RoundingMode.CEILING));
            list.add(BigDecimal.valueOf((monthNumber / 6) * monthNumber * 5 * 1.09).setScale(2, RoundingMode.CEILING));
            list.add(BigDecimal.valueOf((monthNumber / 6) * monthNumber * 5 * 1.101).setScale(2, RoundingMode.CEILING));
            list.add(BigDecimal.valueOf((monthNumber / 6) * monthNumber * 5 * 1.49).setScale(2, RoundingMode.CEILING));
            list.add(BigDecimal.valueOf((monthNumber / 6) * monthNumber * 5 * 1.2).setScale(2, RoundingMode.CEILING));
            list.add(BigDecimal.valueOf(i / (monthNumber / 4) * 0.985).setScale(2, RoundingMode.CEILING));
            fakeMap.put(i, list);
        }
        List<BigDecimal> result = new ArrayList<>();
        if (month != null) {
            result = fakeMap.get(month);
        } else {
            TreeMap<Integer, BigDecimal> sumMap = new TreeMap<>();
            fakeMap.forEach((k, v) -> {
                for (int i = 0; i < v.size(); i++) {
                    BigDecimal total = sumMap.getOrDefault(i, BigDecimal.ZERO);
                    total = total.add(v.get(i));
                    sumMap.put(i, total);
                }
            });
            List<BigDecimal> finalResult = result;
            sumMap.forEach((k, v) -> {
                finalResult.add(v);
            });
        }
        //模拟数据
        vo.setOil(result.get(0));
        vo.setGas(result.get(1));
        vo.setLastMonthCost(result.get(2));
        vo.setWater(result.get(3));
        vo.setElectric(result.get(4));
        vo.setEffective(result.get(5));
        return vo;
    }

    /**
     * 经营综合概览-销售计划
     *
     * @param month 月份
     * @return Map<String, List < MonthValue>>
     */
    @Override
    public List<MonthValue> salePlan(Integer month, String mineCode) {
        Date[] dateRange = DateUtils.getDateRange(DateUtil.year(new Date()), month);
        Map<Integer, BigDecimal> planSaleOfMonth = statisticMapper.planSaleOfMonth(dateRange[0], dateRange[1], mineCode).stream().collect(Collectors.toMap(MonthValue::getMonth, MonthValue::getTotal));

        DynamicDataSourceContextHolder.push("shipped");
        Map<Integer, BigDecimal> realSaleOfMonth = statisticMapper.realSaleOfMonth(dateRange[0], dateRange[1], mineCode).stream().collect(Collectors.toMap(MonthValue::getMonth, MonthValue::getTotal2));
        DynamicDataSourceContextHolder.clear();

        List<MonthValue> result = new ArrayList<>();
        for (int i = 1; i < 13; i++) {
            BigDecimal plan = planSaleOfMonth.getOrDefault(i, BigDecimal.ZERO).divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING);
            BigDecimal sale = realSaleOfMonth.getOrDefault(i, BigDecimal.ZERO).divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING);
            MonthValue vo = new MonthValue(i);
            vo.setTotal(plan);
            vo.setTotal2(sale);
            if (month != null && month != i) {
                continue;
            }
            result.add(vo);
        }
        return result;
    }

    @Override
    public List<MonthValue> gtySalePlan(Integer month, String mineCode) {

        Date[] dateRange = DateUtils.getDateRange(DateUtil.year(new Date()), month);
        Map<Integer, BigDecimal> planSaleOfMonth = statisticMapper.planSaleOfMonth(dateRange[0], dateRange[1], mineCode).stream().collect(Collectors.toMap(MonthValue::getMonth, MonthValue::getTotal));
        Map<Integer, BigDecimal> realSaleOfMonth = statisticMapper.salveCount(dateRange[0], dateRange[1], mineCode).stream().collect(Collectors.toMap(MonthValue::getMonth, MonthValue::getTotal2));

        List<MonthValue> result = new ArrayList<>();
        for (int i = 1; i < 13; i++) {
            BigDecimal plan = planSaleOfMonth.getOrDefault(i, BigDecimal.ZERO).divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP);
            BigDecimal sale = realSaleOfMonth.getOrDefault(i, BigDecimal.ZERO).divide(Constants.TEN_THOUSAND, 2, RoundingMode.HALF_UP);
            MonthValue vo = new MonthValue(i);
            vo.setTotal(plan);
            vo.setTotal2(sale);
            if (month != null && month != i) {
                continue;
            }
            result.add(vo);
        }
        return result;
    }

    @Override
    public List<MonthValue> gtySaleCompanyPlan(Integer month, String companyCode) {

        Date[] dateRange = DateUtils.getDateRange(DateUtil.year(new Date()), month);
        Map<Integer, BigDecimal> planSaleOfMonth = statisticMapper.planSaleCompanyOfMonth(dateRange[0], dateRange[1], companyCode).stream().collect(Collectors.toMap(MonthValue::getMonth, MonthValue::getTotal));
        Map<Integer, BigDecimal> realSaleOfMonth = statisticMapper.salveCompanyCount(dateRange[0], dateRange[1], companyCode).stream().collect(Collectors.toMap(MonthValue::getMonth, MonthValue::getTotal2));

        List<MonthValue> result = new ArrayList<>();
        for (int i = 1; i < 13; i++) {
            BigDecimal plan = planSaleOfMonth.getOrDefault(i, BigDecimal.ZERO).divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING);
            BigDecimal sale = realSaleOfMonth.getOrDefault(i, BigDecimal.ZERO).divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING);
            MonthValue vo = new MonthValue(i);
            vo.setTotal(plan);
            vo.setTotal2(sale);
            if (month != null && month != i) {
                continue;
            }
            result.add(vo);
        }
        return result;
    }

    @Override
    public List<MonthValue> groupSaleCompanyPlan(Integer month, String companyCode) {


        Date[] dateRange = DateUtils.getDateRange(DateUtil.year(new Date()), month);
        List<MonthValue> list = statisticMapper.groupPlanSaleCompanyOfMonth(dateRange[0], dateRange[1], companyCode);
        Map<Integer, BigDecimal> execSaleOfMonth = list.stream().collect(Collectors.toMap(MonthValue::getMonth, MonthValue::getTotal));
        Map<Integer, BigDecimal> planSaleOfMonth = list.stream().collect(Collectors.toMap(MonthValue::getMonth, MonthValue::getTotal2));

        List<MonthValue> result = new ArrayList<>();
        for (int i = 1; i < 13; i++) {
            BigDecimal plan = planSaleOfMonth.getOrDefault(i, BigDecimal.ZERO).divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING);
            BigDecimal sale = execSaleOfMonth.getOrDefault(i, BigDecimal.ZERO).divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING);
            MonthValue vo = new MonthValue(i);
            vo.setTotal(plan);
            vo.setTotal2(sale);
            if (month != null && month != i) {
                continue;
            }
            result.add(vo);
        }
        return result;
    }

    @Override
    public List<ExecutionSalesVo> executionSaleCount(SalesPlanReq req) {
        Calendar cal = Calendar.getInstance();

        if (!StrUtil.isBlank(req.getMonth()) && Integer.parseInt(req.getMonth()) < 10) {
            req.setDate("0" + req.getMonth());
        }
        if (!StrUtil.isBlank(req.getDate())) {
            req.setDate(cal.getWeekYear() + "-" + req.getDate());
        }
        return statisticMapper.executionSaleCount(req);
    }

    @Override
    public List<ExecutionSalesVo> groupExecutionSaleCount(SalesPlanReq req) {
        Calendar c = Calendar.getInstance();
        // 获取当前的年份
        int year = c.get(Calendar.YEAR);

        if (!StrUtil.isBlank(req.getMonth())) {
            req.setType("1");
            req.setDate(Integer.parseInt(req.getMonth()) < 10 ? year + "-0" + req.getMonth() : year + "-" + req.getMonth());
        } else {
            req.setType("2");
            req.setDate(year + "");
        }
        return statisticMapper.groupExecutionSaleCount(req);
    }


    @Override
    public List<ExecutionSalesVo> SaleBarChartCount(SalesPlanReq req) throws IllegalAccessException {

        List<ExecutionSalesVo> saleList = statisticMapper.SaleBarChartCount(req);
        List<ExecutionSalesVo> saleNewList = statisticMapper.SaleBarChartCount(req);

        List<ExecutionSalesVo> resList = saleDataAnalysisService.comparisonOfSalesData(req);

        boolean home = true;
        boolean outer = true;
        boolean outerRailway = true;
        List<String> lastsixMonthsList = lastsixMonths();
        //&&saleList.get(j).getSalesVolume().compareTo(new BigDecimal(0))!=0

        for (int i = 0; i < lastsixMonths().size(); i++) {

            String date = lastsixMonthsList.get(i);

            for (int j = 0; j < saleList.size(); j++) {

                String saleListDate = saleList.get(j).getSalesDate();
                String salesDestination = saleList.get(j).getSalesDestination();
                if (date.equals(saleListDate)) {
                    if (date.equals(saleListDate) && !StrUtil.isBlank(salesDestination) && salesDestination.equals("0")) {
                        home = false;
                    }
                    if (date.equals(saleListDate) && !StrUtil.isBlank(salesDestination) && salesDestination.equals("2")) {
                        outer = false;
                    }
                    if (date.equals(saleListDate) && !StrUtil.isBlank(salesDestination) && salesDestination.equals("1")) {
                        outerRailway = false;
                    }

                }
                if (j == saleList.size() - 1) {
                    if (home) {
                        ExecutionSalesVo v = new ExecutionSalesVo();
                        v.setSalesDate(date);
                        v.setSalesVolume(new BigDecimal(0));
                        v.setSalesDestination("0");
                        saleNewList.add(v);
                    }
                    if (outer) {
                        ExecutionSalesVo v = new ExecutionSalesVo();
                        v.setSalesDate(date);
                        v.setSalesVolume(new BigDecimal(0));
                        v.setSalesDestination("2");
                        saleNewList.add(v);
                    }
                    if (outerRailway) {
                        ExecutionSalesVo v = new ExecutionSalesVo();
                        v.setSalesDate(date);
                        v.setSalesVolume(new BigDecimal(0));
                        v.setSalesDestination("1");
                        saleNewList.add(v);
                    }
                    home = true;
                    outer = true;
                    outerRailway = true;
                }
            }
        }
        // 新增环比 同比数据
        Map<String, ExecutionSalesVo> resMap = new HashMap<>();
        for (ExecutionSalesVo res : resList) {
            resMap.put(res.getSalesDate(), res);
        }
        // 遍历 saleNewList，并根据销售日期匹配复制数据
        for (ExecutionSalesVo item : saleNewList) {
            String salesDate = item.getSalesDate();
            if (resMap.containsKey(salesDate)) {
                ExecutionSalesVo res = resMap.get(salesDate);
                item.setMonthOnMonthData(res.getMonthOnMonthData());
                item.setYearOnYearData(res.getYearOnYearData());
            }
        }
        saleNewList.sort((s1, s2) -> s2.getSalesDate().compareTo(s1.getSalesDate()));

        return saleNewList;
    }

    @Override
    public List<ExecutionSalesVo> GroupSaleBarChartCount(SalesPlanReq req) {
        List<ExecutionSalesVo> saleList = statisticMapper.GroupSaleBarChartCount(req);
        return saleList;
    }

    @Override
    public List<EnvironmentProtectionVo> getEnvironmentProtection() throws Exception {
        List<EnvironmentProtectionVo> recordsList = new ArrayList<>();

        String url = API_URL + "information/pollution/listA3?createTimeBegin=2024-06-25+00:00:00&createTimeEnd=2024-06-25+23:59:59&currentDeptNo=A03&pageNo=1&pageSize=7";
        String json = sendGet(url);
//        String json = sendGet(url);

        if (json != null && !json.isEmpty()) {
//            EnvironmentProtection parser = new EnvironmentProtection();

            JSONObject jsonObject = JSONUtil.parseObj(json);
            System.out.println("jsonObject=========" + jsonObject);
            JSONObject result = jsonObject.getJSONObject("result");
            JSONArray records = result.getJSONArray("records");
            for (int i = 0; i < records.size(); i++) {
                JSONObject recordJson = records.getJSONObject(i);

                EnvironmentProtectionVo record = new EnvironmentProtectionVo();
                record.setEquipmentName(recordJson.getStr("equipmentName"));
                record.setMn(recordJson.getStr("mn"));
                record.setInstantaneousFlow(recordJson.getStr("instantaneousFlow"));
                record.setNh4n(recordJson.getStr("nh4n"));
                record.setDataTime(recordJson.getStr("dataTime"));
                record.setPh(recordJson.getStr("ph"));
                record.setCod(recordJson.getStr("cod"));
                record.setTp(recordJson.getStr("tp"));
                recordsList.add(record);
            }
            statisticMapper.insertEnvironmentProtectionList(recordsList);
        }
        return recordsList;
    }

    @Override
    public List<EnvironmentProtectionVo> selectEnvironmentProtection() throws Exception {

        return statisticMapper.selectEnvironmentProtection();


    }

    @Override
    public List<EnvironmentProtectionVo> getMonitoringData() throws Exception {
        List<EnvironmentProtectionVo> recordsList = new ArrayList<>();

        String url = API_URL + "information/statistic/totalEmissionsA?orgCode=A03";
        String json = sendGet(url);

        if (json != null && !json.isEmpty()) {
            com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(json);
            com.alibaba.fastjson.JSONObject result = jsonObject.getJSONObject("result");

            EnvironmentProtectionVo record = new EnvironmentProtectionVo();
            record.setDateRange(result.getString("dateRange"));
            record.setTotalFlow((result.getString("totalFlow")));
            record.setTotalNh4n((result.getString("totalNh4n")));
            record.setDomesticWaterCOD((result.getString("domesticWaterCOD")));
            record.setMineWaterCOD((result.getString("mineWaterCOD")));
            record.setWasteWaterCOD((result.getString("wasteWaterCOD")));
            record.setMineWaterNh4n((result.getString("mineWaterNh4n")));
            record.setDomesticWaterNh4n((result.getString("domesticWaterNh4n")));
            record.setWasteWaterNh4n((result.getString("wasteWaterNh4n")));

            recordsList.add(record);
        }

        return recordsList;
    }

    @Override
    public Double getEfficientTransmissionByMonth() throws Exception {
//        List<EnvironmentProtection> recordsList = new ArrayList<>();
        double effectiveRate = 0;
        String url = API_URL + "chartInterface/getEffectiveRate-3?date=2024-6";
        String json = sendGet(url);

        if (json != null && !json.isEmpty()) {
            EnvironmentProtectionVo parser = new EnvironmentProtectionVo();
            // 使用 FastJSON 解析 JSON 字符串为 JSONObject
            com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(json);


            // 获取嵌套的 JSONObject (result)
            com.alibaba.fastjson.JSONObject resultObj = jsonObject.getJSONObject("result");
            effectiveRate = resultObj.getDoubleValue("effectiveRate");
        }
        return effectiveRate;
    }


    public List<String> lastsixMonths() {
        List<String> resultList = new ArrayList<String>();
        Calendar cal = Calendar.getInstance();
        //近六个月
        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + 1);
        for (int i = 0; i < 6; i++) {
            cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) - 1);
            resultList.add(String.valueOf(cal.get(Calendar.YEAR))
                    + "-" + (cal.get(Calendar.MONTH) + 1 < 10 ? "0" +
                    (cal.get(Calendar.MONTH) + 1) : (cal.get(Calendar.MONTH) + 1)));
        }
        return resultList;
    }

    /**
     * 近六月数据的环比月
     */
    public List<String> lastMonths() {
        List<String> resultList = new ArrayList<String>();
        Calendar cal = Calendar.getInstance();
        //近六个月 环比
        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH));
        for (int i = 0; i < 6; i++) {
            cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) - 1);
            resultList.add(String.valueOf(cal.get(Calendar.YEAR))
                    + "-" + (cal.get(Calendar.MONTH) + 1 < 10 ? "0" +
                    (cal.get(Calendar.MONTH) + 1) : (cal.get(Calendar.MONTH) + 1)));
        }
        return resultList;
    }

    /**
     * 近六月数据的同比年
     */
    public List<String> lastYears() {
        List<String> resultList = new ArrayList<String>();
        Calendar cal = Calendar.getInstance();
        //近六个月
        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + 1);
        for (int i = 0; i < 6; i++) {
            cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) - 1);
            resultList.add(String.valueOf(cal.get(Calendar.YEAR))
                    + "-" + (cal.get(Calendar.MONTH) + 1 < 10 ? "0" +
                    (cal.get(Calendar.MONTH) + 1) : (cal.get(Calendar.MONTH) + 1)));
        }
        return resultList;
    }

    @Override
    public List<ProductionMarketingCountVo> selectProductionMarketing(ProductionMarketingCountReq req) {
        return statisticMapper.selectProductionMarketing(req);
    }

    @Override
    public ProductionMarketingCountVo selectProductionMarketingCountByCoalType(ProductionMarketingCountReq req) {


        ProductionMarketingCountVo p = statisticMapper.selectProductionMarketingCountByCoalType(req);
        if (StrUtil.isBlank(req.getCoalType())) {
            p.setProductionMarketingName("北能合计");
        } else if (req.getCoalType().equals("1")) {
            p.setProductionMarketingName("井工矿合计");
        } else if (req.getCoalType().equals("2")) {
            p.setProductionMarketingName("露天矿合计");
        }
        p.setOverallStrippingRatio(p.getCountYield().compareTo(new BigDecimal(0)) == 0 ? new BigDecimal(0) : p.getCountPeel().divide(p.getCountYield(), 2));
        p.setInternalCoalSupply(p.getTotalSales().compareTo(new BigDecimal(0)) == 0 ? new BigDecimal(0) : p.getInternalCoalSupply().divide(p.getTotalSales(), 2));
        return p;
    }

    /**
     * 生产成本分析-其他生产成本
     *
     * @param year 年份
     * @return Map<String, ExecutionCostVO>
     */
    @Override
    public List<MonthValue> otherCost(Integer year, Integer month, String mineCode) {
        Date[] dateRange = DateUtils.getDateRangeUtilNow(year, month);
        List<MonthValue> costList = statisticMapper.sumCost(dateRange[0], dateRange[1], mineCode);
        Map<String, Date[]> stringMap = DateUtils.calculateComparisonDateRange(year);
        Date[] moMDateRange = getMoMDateRange(dateRange[0], dateRange[1]);
        List<MonthValue> result = new ArrayList<>();

        DynamicDataSourceContextHolder.push("energy");
        Map<Integer, MonthValue> energyMap = statisticMapper.sumEnergyCost(dateRange[0], dateRange[1], mineCode)
                .stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));

        Map<Integer, MonthValue> TongenergyMap = statisticMapper.sumEnergyCost(stringMap.get("yearOnYear")[0], stringMap.get("yearOnYear")[1], mineCode)
                .stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));

        Map<Integer, MonthValue> moMenergyMap = statisticMapper.sumEnergyCost(moMDateRange[0], moMDateRange[1], mineCode)
                .stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));
        DynamicDataSourceContextHolder.clear();
        Map<Integer, MonthValue> adjustedMoMenergyMap = moMenergyMap.entrySet().stream()
                .collect(Collectors.toMap(entry -> (entry.getKey() % 12) + 1, Map.Entry::getValue));
        for (int i = 1; i < DateUtil.month(dateRange[1]) + 2; i++) {
            int finalI = i;
            if (month != null && month != finalI) {
                continue;
            }
            MonthValue energy = energyMap.getOrDefault(i, new MonthValue(i));
            MonthValue Tongenergy = TongenergyMap.getOrDefault(i, new MonthValue(i));
            MonthValue Momenergy = adjustedMoMenergyMap.getOrDefault(i, new MonthValue(i));
            MonthValue executionCost = costList.stream().filter(o -> Convert.toInt(o.getMonth(), -1) == finalI).findFirst().orElse(new MonthValue(finalI));
            executionCost.setTotal3(energy.getTotal());
            executionCost.setTotal4(energy.getTotal2());


            BigDecimal total5Value = BigDecimal.ZERO;
            if (Tongenergy.getTotal2().compareTo(BigDecimal.ZERO) != 0) {
                total5Value = energy.getTotal2().subtract(Tongenergy.getTotal2()).divide(Tongenergy.getTotal2(), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            }
            executionCost.setTotal5(total5Value);

            BigDecimal total6Value = BigDecimal.ZERO;
            if (Momenergy.getTotal2().compareTo(BigDecimal.ZERO) != 0) {
                total6Value = energy.getTotal2().subtract(Momenergy.getTotal2()).divide(Momenergy.getTotal2(), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            }
            executionCost.setTotal6(total6Value);

//            executionCost.setTotal5(energy.getTotal2().subtract(Tongenergy.getTotal2()).divide(Tongenergy.getTotal2(),2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")));
//            executionCost.setTotal6(energy.getTotal2().subtract(Momenergy.getTotal2()).divide(Momenergy.getTotal2(),2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")));
            result.add(executionCost);
        }
        return result;
    }


    /**
     * 生产综合能效分析-采掘比
     *
     * @param year 年份
     * @return Map<String, BigDecimal>
     */
    @Override
    public List<MonthValue> drivagePercent(Integer year, String mineCode) {
        Date[] dateRange = DateUtils.getDateRangeUtilNow(year, null);
        Map<Integer, MonthValue> outputMap = statisticMapper.sumOutput(dateRange[0], dateRange[1], mineCode).stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));
        List<MonthValue> result = new ArrayList<>();
        for (int i = 1; i < DateUtil.month(dateRange[1]) + 2; i++) {
            MonthValue vo = outputMap.getOrDefault(i, new MonthValue(i));
            BigDecimal percent = Constants.ZERO;
            if (vo != null && vo.getTotal().compareTo(BigDecimal.ZERO) > 0) {
                percent = vo.getTotal2().multiply(Constants.HUNDRED).divide(vo.getTotal(), 2, RoundingMode.CEILING);
            }
            vo.setTotal(percent);
            result.add(vo);
        }
        return result;
    }

    /**
     * 生产综合能效分析-销售计划与执行
     *
     * @param year 年份
     * @return Map<Integer, MonthValue>
     */
    @Override
    public List<MonthValue> salePlanAndExecution(Integer year, String mineCode) {
        Date[] dateRange = DateUtils.getDateRange(year, null);
        Map<Integer, BigDecimal> planSaleOfMonth = statisticMapper.planSaleOfMonth(dateRange[0], dateRange[1], mineCode).stream().collect(Collectors.toMap(MonthValue::getMonth, MonthValue::getTotal));

        DynamicDataSourceContextHolder.push("shipped");
        Map<Integer, BigDecimal> realSaleOfMonth = statisticMapper.realSaleOfMonth(dateRange[0], dateRange[1], mineCode).stream().collect(Collectors.toMap(MonthValue::getMonth, MonthValue::getTotal2));
        DynamicDataSourceContextHolder.clear();

        List<MonthValue> result = new ArrayList<>();
        for (int i = 1; i < 13; i++) {
            BigDecimal plan = planSaleOfMonth.getOrDefault(i, BigDecimal.ZERO).divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING);
            BigDecimal sale = realSaleOfMonth.getOrDefault(i, BigDecimal.ZERO).divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING);
            MonthValue vo = new MonthValue(i);
            vo.setTotal(plan);
            vo.setTotal2(sale);
            result.add(vo);
        }
        return result;
    }

    /**
     * 生产综合能效分析-能效趋势
     *
     * @param year 年份
     * @return Map<Integer, MonthValue>
     */
    @Override
    public List<MonthValue> efficiencyTrend(Integer year, String mineCode) {
        Date[] dateRange = DateUtils.getDateRangeUtilNow(year, null);
        List<MonthValue> result = new ArrayList<>();
        List<MonthValue> monthValueList = statisticMapper.sumCostAndRealOutput(dateRange[0], dateRange[1], mineCode);

        DynamicDataSourceContextHolder.push("energy");
        Map<Integer, MonthValue> energyMap = statisticMapper.sumEnergyCost(dateRange[0], dateRange[1], mineCode)
                .stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));
        DynamicDataSourceContextHolder.clear();

        for (int i = 1; i < DateUtil.month(dateRange[1]) + 2; i++) {
            int finalI = i;
            MonthValue monthValue = monthValueList.stream().filter(o -> o.getMonth() != null && o.getMonth() == finalI).findFirst().orElse(new MonthValue(finalI));
            MonthValue energy = energyMap.getOrDefault(i, new MonthValue(i));
            monthValue.setTotal3(energy.getTotal());
            monthValue.setTotal4(energy.getTotal2());
            result.add(monthValue);
        }
        return result;
    }

    /**
     * 生产综合能效分析-产量计划与执行
     *
     * @param year 年份
     * @return Map<Integer, MonthValue>
     */
    @Override
    public List<MonthValue> planOutputAndRealOutput(Integer year, String mineCode) {

        Date[] dateRange = DateUtils.getDateRange(year, null);
        List<MonthValue> result = new ArrayList<>();
        List<MonthValue> monthValueList = statisticMapper.sumPlanOutputAndRealOutput(dateRange[0], dateRange[1], mineCode);
        for (int i = 1; i < 13; i++) {
            int finalI = i;
            MonthValue monthValue = monthValueList.stream().filter(o -> o.getMonth() != null && o.getMonth() == finalI).findFirst().orElse(new MonthValue(finalI));
            monthValue.setTotal(monthValue.getTotal().divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING));
            monthValue.setTotal2(monthValue.getTotal2().divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING));
            result.add(monthValue);
        }
        return result;
    }

    /**
     * 生产综合能效分析-产量与销售
     *
     * @param year 年份
     * @return Map<Integer, MonthValue>
     */
    @Override
    public List<MonthValue> realOutputAndSale(Integer year, String mineCode) {
        Date[] dateRange = DateUtils.getDateRangeUtilNow(year, null);
        List<MonthValue> result = new ArrayList<>();

        Map<Integer, BigDecimal> realOutputOfMonth = statisticMapper.sumRealOutput(dateRange[0], dateRange[1], mineCode).stream().collect(Collectors.toMap(MonthValue::getMonth, MonthValue::getTotal));
        DynamicDataSourceContextHolder.push("shipped");
        Map<Integer, BigDecimal> realSaleOfMonth = statisticMapper.realSaleOfMonth(dateRange[0], dateRange[1], mineCode).stream().collect(Collectors.toMap(MonthValue::getMonth, MonthValue::getTotal2));
        DynamicDataSourceContextHolder.clear();

        for (int i = 1; i < DateUtil.month(dateRange[1]) + 2; i++) {
            BigDecimal output = realOutputOfMonth.getOrDefault(i, BigDecimal.ZERO).divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING);
            BigDecimal sale = realSaleOfMonth.getOrDefault(i, BigDecimal.ZERO).divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING);
            MonthValue vo = new MonthValue(i);
            vo.setTotal(output);
            vo.setTotal2(sale);
            result.add(vo);
        }
        return result;
    }

    /**
     * 生产综合能效分析-吨煤生产成本
     *
     * @param year 年份
     * @return Map<Integer, BigDecimal>
     */
    @Override
    public List<MonthValue> coalProductCost(Integer year, String mineCode) {
        List<MonthValue> result = new ArrayList<>();
        Date[] dateRange = DateUtils.getDateRangeUtilNow(year, null);
        //实际产量
        Map<Integer, BigDecimal> realOutputOfMonth = statisticMapper.sumRealOutput(dateRange[0], dateRange[1], mineCode).stream().collect(Collectors.toMap(MonthValue::getMonth, MonthValue::getTotal));
        //水费+电费 总消耗量
        DynamicDataSourceContextHolder.push("energy");
        Map<Integer, MonthValue> costOfMonth = statisticMapper.sumEnergyCost(dateRange[0], dateRange[1], mineCode).stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));
        DynamicDataSourceContextHolder.clear();

        for (int i = 1; i < DateUtil.month(dateRange[1]) + 2; i++) {
            BigDecimal output = realOutputOfMonth.getOrDefault(i, BigDecimal.ZERO);
            MonthValue costOBj = costOfMonth.getOrDefault(i, new MonthValue(i));
            MonthValue vo = new MonthValue(i);
            BigDecimal cost = costOBj.getTotal().add(costOBj.getTotal2());
            vo.setTotal(output.compareTo(BigDecimal.ZERO) > 0 ? cost.divide(output, 2, RoundingMode.CEILING) : BigDecimal.ZERO);
            result.add(vo);
        }
        return result;
    }


    /**
     * 生产综合能效分析-全员工效
     *
     * @param year 年份
     * @return Map<Integer, BigDecimal>
     */
    @Override
    public List<MonthValue> staffWork(Integer year, String mineCode) {
        List<MonthValue> result = new ArrayList<>();
        Date[] dateRange = DateUtils.getDateRangeUtilNow(year, null);

//        DynamicDataSourceContextHolder.push("slave");
//        Map<Integer, MonthValue> numberMap = statisticMapper.selectStaffNumberOfMonth(dateRange[0], dateRange[1],mineCode)
//                .stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));
//        DynamicDataSourceContextHolder.clear();
        //2023-2-28修改
        Map<Integer, MonthValue> numberMap = statisticMapper.selectAttendanceEfficiencyByYears(String.valueOf(year), mineCode)
                .stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));

        //产量
        Map<Integer, MonthValue> outputMap = statisticMapper.sumRealOutput(dateRange[0], dateRange[1], mineCode)
                .stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));
        for (int i = 1; i < DateUtil.month(dateRange[1]) + 2; i++) {
            MonthValue numberValue = numberMap.get(i);
            if (numberValue != null && numberValue.getTotal().compareTo(BigDecimal.ZERO) > 0) {
                MonthValue outputValue = outputMap.get(i);
                if (outputValue != null) {
                    outputValue.setTotal(outputValue.getTotal().divide((numberValue.getTotal()), 2, RoundingMode.CEILING));
                    result.add(outputValue);
                    continue;
                }
            }
            result.add(new MonthValue(i));
        }
        return result;
    }

    /**
     * 生产综合能效分析-回采/掘进趋势
     *
     * @param type 回采0 掘进 1
     * @param year 年份
     * @return Map<Integer, MonthValue>
     */
    @Override
    public List<MonthValue> miningOrDrivageTrend(Integer type, Integer year, String mineCode) {
        List<MonthValue> result = new ArrayList<>();
        if (type == null) {
            return result;
        }
        Date[] dateRange = DateUtils.getDateRangeUtilNow(year, null);
        List<MonthValue> monthValueList = statisticMapper.miningOrDrivageTrend(dateRange[0], dateRange[1], type + StrUtil.EMPTY, mineCode);

        for (int i = 1; i < DateUtil.month(dateRange[1]) + 2; i++) {
            int finalI = i;
            MonthValue monthValue = monthValueList.stream().filter(o -> o.getMonth() != null && o.getMonth() == finalI).findFirst().orElse(new MonthValue(finalI));
            monthValue.setTotal(monthValue.getTotal().divide(Constants.TEN_THOUSAND, 2, RoundingMode.CEILING));
            result.add(monthValue);
        }
        return result;
    }

    @Override
    public List<MonthYieldVo> yieldStatisticalAnalysis(Integer year, Integer month, String mineCode) {
        String lastMonths[] = DateUtils.getLastMonth(new SimpleDateFormat("yyyy-MM-dd").format(new Date()), 1);
        //获取月初和月末

        if (month == null || year == null) {
            throw new HuaNengException(Constants.FAIL, "年月不能为空");
        } else {
            Calendar cal = Calendar.getInstance();
            //清除可能存在的缓存
            cal.clear();
            //设置年份
            cal.set(Calendar.YEAR, year);
            //设置月份
            cal.set(Calendar.MONTH, month - 1);
            //获取某月最小天数
            int firstDay = cal.getMinimum(Calendar.DATE);
            //设置日历中月份的最小天数
            cal.set(Calendar.DAY_OF_MONTH, firstDay);

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            int y = calendar.get(Calendar.YEAR); //当前年份
            int m = calendar.get(Calendar.MONTH) + 1;
            if (DateUtils.checkDate(new Date(), cal.getTime())) {
                throw new HuaNengException(Constants.FAIL, "当前月数据不完整，次月后查看");
            } else if (y == year && m == month) {
                throw new HuaNengException(Constants.FAIL, "当前月数据不完整，次月后查看");
            }
        }

        Date[] dateRange = DateUtils.getDateRange(year, month);
        Date[] yearDateRange = DateUtils.getDateRange(year, null);
        Date yearStartDate = yearDateRange[0];
        Date yearEndDate = yearDateRange[1];
        Date monthStartDate = dateRange[0];
        Date monthEndDate = dateRange[1];

        MonthYieldVo yield = statisticMapper.planYield(monthStartDate, monthEndDate, yearStartDate, yearEndDate, mineCode);//月计划产量和年计划产量
        MonthYieldVo actual = statisticMapper.planActual(monthStartDate, monthEndDate, yearStartDate, yearEndDate, mineCode);//月实际产量和年实际产量和月实际进尺和年实际进尺
//        MonthYieldVo mining = statisticMapper.planMining(monthStartDate, monthEndDate,yearStartDate,yearEndDate, mineCode);//回采年累计计划，年计划，进尺月计划
        MonthYieldVo drivage = statisticMapper.planDrivage(monthStartDate, monthEndDate, yearStartDate, yearEndDate, mineCode);//掘进年累计计划，年计划，进尺月计划
        MonthYieldVo planSale = statisticMapper.planSale(monthStartDate, monthEndDate, yearStartDate, yearEndDate, mineCode);//计划销售
        MonthYieldVo planActualSale = statisticMapper.planActualSale(monthStartDate, monthEndDate, yearStartDate, yearEndDate, mineCode);//实际销售
        MonthYieldVo detBackCoal = statisticMapper.backCoal(monthStartDate, monthEndDate, mineCode);//自用煤
        MonthYieIdStatisticsVo monthYieIdStatisticsVo = new MonthYieIdStatisticsVo();
        List<MonthYieldVo> monthYieldVos = new ArrayList<>();
        //产量
        MonthYieldVo monthYieldVo = new MonthYieldVo();
        MonthYieldVo monthYieldVo1 = new MonthYieldVo();
        MonthYieldVo monthYieldVo2 = new MonthYieldVo();
        MonthYieldVo monthYieldVo3 = new MonthYieldVo();
        MonthYieldVo monthYieldVo4 = new MonthYieldVo();
        monthYieldVo.setPlanOutput(yield.getPlanOutput());
        monthYieldVo.setOutput(actual.getOutput());
        monthYieldVo.setMonthOverabundance(actual.getOutput().subtract(yield.getPlanOutput()));//超欠
        monthYieldVo.setAvgOutput(actual.getOutput().divide(new BigDecimal("31"), 2, BigDecimal.ROUND_CEILING));
        monthYieldVo.setYearCumulativePlan(yield.getYearCumulativePlan());//年累计计划
        monthYieldVo.setYearCumulativeCompletion(actual.getOutputYear());//年累计完成
        monthYieldVo.setYearOverabundance(actual.getOutputYear().subtract(yield.getYearCumulativePlan()));//年超欠
        monthYieldVo.setYearPlan(yield.getYearPlan());//年度计划
        BigDecimal com1 = new BigDecimal("0");
        com1 = com1.add(actual.getOutputYear());
        if (com1.compareTo(new BigDecimal("0")) == 0) {
            monthYieldVo.setYearCompletionRate(new BigDecimal("0"));
        } else {
            if (yield.getYearPlan().compareTo(new BigDecimal("0")) == 0) {
                monthYieldVo.setYearCompletionRate(new BigDecimal("0"));//年度百分比
            } else {
                monthYieldVo.setYearCompletionRate(actual.getOutputYear().divide(yield.getYearPlan(), 2, BigDecimal.ROUND_CEILING).multiply(new BigDecimal("100")));//年度百分比
            }

        }
        monthYieldVo.setCoalName("产量(t)");

        monthYieldVo1.setPlanOutput(drivage.getPlanFootageMonth());//进尺月度计划量
        monthYieldVo1.setOutput(actual.getFootageMonth());//月实际完成进尺
        monthYieldVo1.setMonthOverabundance(actual.getFootageMonth().subtract(monthYieldVo1.getPlanOutput()));//超欠
        monthYieldVo1.setAvgOutput(actual.getFootageMonth().divide(new BigDecimal("31"), 2, BigDecimal.ROUND_CEILING));//平均日产
        monthYieldVo1.setYearCumulativePlan(drivage.getYearCumulativePlan());//年累计计划
        monthYieldVo1.setYearCumulativeCompletion(actual.getFootageYear());//年累计完成
        monthYieldVo1.setYearOverabundance(monthYieldVo1.getYearCumulativeCompletion().subtract(monthYieldVo1.getYearCumulativePlan()));//超欠
        monthYieldVo1.setYearPlan(drivage.getYearPlan());//年度计划
        BigDecimal yearCCompletion = new BigDecimal("0");
        yearCCompletion = yearCCompletion.add(monthYieldVo1.getYearCumulativeCompletion());
        if (yearCCompletion.compareTo(new BigDecimal("0")) == 0) {
            monthYieldVo1.setYearCompletionRate(new BigDecimal("0"));
        } else {
            if (monthYieldVo1.getYearPlan().compareTo(new BigDecimal("0")) == 0) {
                monthYieldVo1.setYearCompletionRate(new BigDecimal("0"));
            } else {
                monthYieldVo1.setYearCompletionRate(monthYieldVo1.getYearCumulativeCompletion().divide(monthYieldVo1.getYearPlan(), 2, BigDecimal.ROUND_CEILING).multiply(new BigDecimal("100")));
            }
        }
        monthYieldVo1.setCoalName("进尺(m)");


        monthYieldVo2.setPlanOutput(planSale.getPlanOutput());
        monthYieldVo2.setOutput(planActualSale.getPlanOutput());
        monthYieldVo2.setMonthOverabundance(planActualSale.getPlanOutput().subtract(planSale.getPlanOutput()));
        monthYieldVo2.setAvgOutput(planActualSale.getPlanOutput().divide(new BigDecimal("31"), 2, BigDecimal.ROUND_CEILING));
        monthYieldVo2.setYearCumulativePlan(planSale.getYearCumulativePlan());
        monthYieldVo2.setYearCumulativeCompletion(planActualSale.getYearCumulativeCompletion());
        monthYieldVo2.setYearOverabundance(planActualSale.getYearCumulativeCompletion().subtract(planSale.getYearCumulativePlan()));
        monthYieldVo2.setYearPlan(planSale.getYearPlan());
        BigDecimal com = new BigDecimal("0");
        com = com.add(planActualSale.getYearCumulativeCompletion());
        if (com.compareTo(new BigDecimal("0")) == 0) {
            monthYieldVo2.setYearCompletionRate(new BigDecimal("0"));
        } else {
            if (planSale.getYearPlan().compareTo(new BigDecimal("0")) == 0) {
                monthYieldVo2.setYearCompletionRate(new BigDecimal("0"));
            } else {
                monthYieldVo2.setYearCompletionRate(planActualSale.getYearCumulativeCompletion().divide(planSale.getYearPlan(), 2, BigDecimal.ROUND_CEILING).multiply(new BigDecimal("100")));
            }
        }
        monthYieldVo2.setCoalName("销售(t)");

        monthYieldVo3.setCoalName("自用煤(t)");
        monthYieldVo3.setBackCoal(detBackCoal.getBackCoal());

        monthYieldVo4.setCoalName("库存(t)");
        BigDecimal stock = statisticMapper.stock(year + "-" + Math.abs(month), mineCode);
        monthYieldVo4.setStock(stock);

        monthYieldVos.add(monthYieldVo);
        monthYieldVos.add(monthYieldVo1);
        monthYieldVos.add(monthYieldVo2);
        monthYieldVos.add(monthYieldVo3);
        monthYieldVos.add(monthYieldVo4);

//        monthYieIdStatisticsVo.setBackCoal(detBackCoal.getBackCoal());//自用煤

//        monthYieIdStatisticsVo.setStock(stock);
//        monthYieIdStatisticsVo.setMonthYieldVos(monthYieldVos);
        return monthYieldVos;
    }

    @Override
    public void timingYieldStatisticalAnalysis() {
        String mineCode = "150621011038";
        //1.先查询前6个月库存
        for (int i = 6; i >= 1; i--) {
            String lastMonth[] = DateUtils.getLastMonth(new SimpleDateFormat("yyyy-MM-dd").format(new Date()), i);
            Date[] dateRange = DateUtils.getDateRange(Integer.valueOf(lastMonth[1]), Integer.valueOf(lastMonth[2]));
            Date[] yearDateRange = DateUtils.getDateRange(Integer.valueOf(lastMonth[1]), null);
            Date yearStartDate = yearDateRange[0];
            Date yearEndDate = yearDateRange[1];
            Date monthStartDate = dateRange[0];
            Date monthEndDate = dateRange[1];
            MonthYieldVo actual = statisticMapper.planActual(monthStartDate, monthEndDate, yearStartDate, yearEndDate, mineCode);//月实际产量和年实际产量和月实际进尺和年实际进尺
            MonthYieldVo planActualSale = statisticMapper.planActualSale(monthStartDate, monthEndDate, yearStartDate, yearEndDate, mineCode);//实际销售
            MonthYieldVo detBackCoal = statisticMapper.backCoal(monthStartDate, monthEndDate, mineCode);//自用煤
            BigDecimal zero = new BigDecimal("0");
            //判断月产量、月销量、矸石月产量、煤泥月产量、自用煤量 是否填报
            if (actual.getOutput().compareTo(zero) == 0 && planActualSale.getPlanOutput().compareTo(zero) == 0 &&
                    planActualSale.getShaleAmount().compareTo(zero) == 0 && planActualSale.getCoalSlime().compareTo(zero) == 0
                    && detBackCoal.getBackCoal().compareTo(zero) == 0) {
                continue;
            } else {
                String lastMonths[] = DateUtils.getLastMonth(new SimpleDateFormat("yyyy-MM-dd").format(new Date()), i + 1);//获取前7个月是什么时候
                BigDecimal stock = new BigDecimal("0");
                stock = (statisticMapper.stock(lastMonths[0], mineCode) == null ? new BigDecimal("0") : statisticMapper.stock(lastMonths[0], mineCode));//获取上月库存

                BigDecimal xiaohao = planActualSale.getPlanOutput().add(planActualSale.getShaleAmount()).add(planActualSale.getCoalSlime()).add(detBackCoal.getBackCoal());
                BigDecimal kucun = actual.getOutput().add(stock).subtract(xiaohao); //当月库存
                //插入
                System.out.println(kucun + "-------------------" + lastMonth[0]);
                LambdaQueryWrapper<YieldAnalysis> query = Wrappers.lambdaQuery();
                query.eq(YieldAnalysis::getYears, lastMonth[0]);
                YieldAnalysis yieldAnalysis = yieldAnalysisMapper.selectOne(query);
                YieldAnalysis insertObj = new YieldAnalysis();
                if (yieldAnalysis != null) {
                    insertObj.setYieldId(yieldAnalysis.getYieldId());
                }
                insertObj.setStock(kucun);
                insertObj.setMineCode(mineCode);
                insertObj.setYears(lastMonth[0]);
                yieldAnalysisMapper.insertOrUpdate(insertObj);
            }
        }
    }

    @Override
    public StatisticalYearVo stock(Integer year, String mineCode) {
        StatisticalYearVo statisticalYearVo = statisticMapper.rawCoalStock(String.valueOf(year), mineCode);
        return statisticalYearVo;
    }

    @Override
    public StatisticalYearVo backCoal(Integer year, String mineCode) {
        StatisticalYearVo statisticalYearVo = statisticMapper.rawCoalBackCoal(String.valueOf(year), mineCode);
        return statisticalYearVo;
    }

    @Override
    public StatisticalYearVo coalSlime(Integer year, String mineCode) {
        StatisticalYearVo statisticalYearVo = statisticMapper.rawCoalCoalSlime(String.valueOf(year), mineCode);
        return statisticalYearVo;
    }

    @Override
    public StatisticalYearVo shaleAmount(Integer year, String mineCode) {
        StatisticalYearVo statisticalYearVo = statisticMapper.rawCoalShaleAmount(String.valueOf(year), mineCode);
        return statisticalYearVo;
    }

    @Override
    public StatisticalYearVo sale(Integer year, String mineCode) {
        StatisticalYearVo plan = statisticMapper.rawCoalPlanSale(String.valueOf(year), mineCode);
        StatisticalYearVo iSell = statisticMapper.innerSell(String.valueOf(year), mineCode);
        StatisticalYearVo oSell = statisticMapper.outerSell(String.valueOf(year), mineCode);
        if (plan == null && iSell == null && oSell == null) {
            throw new HuaNengException(Constants.FAIL, "数据不存在");
        }
        plan.setJanActual(iSell.getJanActual().equals("--") && oSell.getJanActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getJanActual().equals("--") ? "0" : iSell.getJanActual()).add(new BigDecimal(oSell.getJanActual().equals("--") ? "0" : oSell.getJanActual()))));
        plan.setFebActual(iSell.getFebActual().equals("--") && oSell.getFebActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getFebActual().equals("--") ? "0" : iSell.getFebActual()).add(new BigDecimal(oSell.getFebActual().equals("--") ? "0" : oSell.getFebActual()))));
        plan.setMarActual(iSell.getMarActual().equals("--") && oSell.getMarActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getMarActual().equals("--") ? "0" : iSell.getMarActual()).add(new BigDecimal(oSell.getMarActual().equals("--") ? "0" : oSell.getMarActual()))));
        plan.setAprActual(iSell.getAprActual().equals("--") && oSell.getAprActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getAprActual().equals("--") ? "0" : iSell.getAprActual()).add(new BigDecimal(oSell.getAprActual().equals("--") ? "0" : oSell.getAprActual()))));
        plan.setMayActual(iSell.getMayActual().equals("--") && oSell.getMayActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getMayActual().equals("--") ? "0" : iSell.getMayActual()).add(new BigDecimal(oSell.getMayActual().equals("--") ? "0" : oSell.getMayActual()))));
        plan.setJunActual(iSell.getJunActual().equals("--") && oSell.getJunActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getJunActual().equals("--") ? "0" : iSell.getJunActual()).add(new BigDecimal(oSell.getJunActual().equals("--") ? "0" : oSell.getJunActual()))));
        plan.setJulActual(iSell.getJulActual().equals("--") && oSell.getJulActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getJulActual().equals("--") ? "0" : iSell.getJulActual()).add(new BigDecimal(oSell.getJulActual().equals("--") ? "0" : oSell.getJulActual()))));
        plan.setAugActual(iSell.getAugActual().equals("--") && oSell.getAugActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getAugActual().equals("--") ? "0" : iSell.getAugActual()).add(new BigDecimal(oSell.getAugActual().equals("--") ? "0" : oSell.getAugActual()))));
        plan.setSeptActual(iSell.getSeptActual().equals("--") && oSell.getSeptActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getSeptActual().equals("--") ? "0" : iSell.getSeptActual()).add(new BigDecimal(oSell.getSeptActual().equals("--") ? "0" : oSell.getSeptActual()))));
        plan.setOctActual(iSell.getOctActual().equals("--") && oSell.getOctActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getOctActual().equals("--") ? "0" : iSell.getOctActual()).add(new BigDecimal(oSell.getOctActual().equals("--") ? "0" : oSell.getOctActual()))));
        plan.setNovActual(iSell.getNovActual().equals("--") && oSell.getNovActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getNovActual().equals("--") ? "0" : iSell.getNovActual()).add(new BigDecimal(oSell.getNovActual().equals("--") ? "0" : oSell.getNovActual()))));
        plan.setDecActual(iSell.getDecActual().equals("--") && oSell.getDecActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getDecActual().equals("--") ? "0" : iSell.getDecActual()).add(new BigDecimal(oSell.getDecActual().equals("--") ? "0" : oSell.getDecActual()))));
        plan.setFirstQuarterActual(iSell.getFirstQuarterActual().equals("--") && oSell.getFirstQuarterActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getFirstQuarterActual().equals("--") ? "0" : iSell.getFirstQuarterActual()).add(new BigDecimal(oSell.getFirstQuarterActual().equals("--") ? "0" : oSell.getFirstQuarterActual()))));
        plan.setSecondQuarterActual(iSell.getSecondQuarterActual().equals("--") && oSell.getSecondQuarterActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getSecondQuarterActual().equals("--") ? "0" : iSell.getSecondQuarterActual()).add(new BigDecimal(oSell.getSecondQuarterActual().equals("--") ? "0" : oSell.getSecondQuarterActual()))));
        plan.setThirdQuarterActual(iSell.getThirdQuarterActual().equals("--") && oSell.getThirdQuarterActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getThirdQuarterActual().equals("--") ? "0" : iSell.getThirdQuarterActual()).add(new BigDecimal(oSell.getThirdQuarterActual().equals("--") ? "0" : oSell.getThirdQuarterActual()))));
        plan.setFourthQuarterActual(iSell.getFourthQuarterActual().equals("--") && oSell.getFourthQuarterActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getFourthQuarterActual().equals("--") ? "0" : iSell.getFourthQuarterActual()).add(new BigDecimal(oSell.getFourthQuarterActual().equals("--") ? "0" : oSell.getFourthQuarterActual()))));
        plan.setYearActual(iSell.getYearActual().equals("--") && oSell.getYearActual().equals("--") ? "--" : String.valueOf(new BigDecimal(iSell.getYearActual().equals("--") ? "0" : iSell.getYearActual()).add(new BigDecimal(oSell.getYearActual().equals("--") ? "0" : oSell.getYearActual()))));
        StatisticalYearVo statisticalYearVo = plan.calculatebackBreak(plan);
        return statisticalYearVo;
    }

    @Override
    public StatisticalWeekVo statisticSale(Date beginDate, Date date, String mineCode) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//        Date[] dateRange = DateUtils.getDateRange(year, null);
//        Date[] yearDateRange = DateUtils.getDateRange(year, null);
//        Date yearStartDate = yearDateRange[0];
//        Date yearEndDate = yearDateRange[1];
//        Date monthStartDate = dateRange[0];
//        Date monthEndDate = dateRange[1];

        //本周 =  周一到周末
        //去年同期 = 去年这周周一的日期到去年这周周末的日期
        //上周 =  上周周一到周末
        //月计划 = 本月第一天和本月最后一天
        //本月完成 = 本月第一天和本周末
        //年度计划  当前年第一天1.1到最后一天12.31
        //本年完成 = 本年第一天到本周末
        //去年同期 = 去年第一天到本周末
        //天数
        Date[] getweek = DateUtils.getweek(0, date);
        Date[] upperGetweek = DateUtils.getweek(-1, date);

        String[] lastMonth = DateUtils.getLastMonth(new SimpleDateFormat("yyyy-MM-dd").format(date), 0);
        String[] firstLast = DateUtils.getLastMonth(new SimpleDateFormat("yyyy-MM-dd").format(date), 1);
        Date[] dateRangeUtilNow = DateUtils.getDateRangeUtilNow(Integer.parseInt(firstLast[1]), Integer.parseInt(firstLast[2]));
        Date[] dateRange = DateUtils.getDateRange(Integer.valueOf(lastMonth[1]), Integer.valueOf(lastMonth[2]));
        Date[] yearDateRange = DateUtils.getDateRange(Integer.valueOf(lastMonth[1]), null);
        Date[] upperYearDateRange = DateUtils.getDateRange(Integer.valueOf(lastMonth[1]) - 1, null);
        Integer[] monthDays = DateUtils.yearMonthWeek();
        int day = DateUtils.getDaysOfMonth(getweek[0]);//天数
        int days = (int) ((beginDate.getTime() - date.getTime()) / (1000 * 3600 * 24));
        int differ = Math.abs(days) + 1; //开始时间与结束时间相差天数
        int currentDays = monthDays[1]; //当前是本月的第几天
        Date upperEndDate = dateRangeUtilNow[1];
        Date currentMonday = getweek[0];//当前周周一
        Date currentSunday = getweek[1];//当前周周末
        Date upperYearMonday = getweek[2];//当前周周一减一年 去年的时间
        Date upperYearSunday = getweek[3];//当前周周末减一年  去年的时间
        Date upperMonday = upperGetweek[0];//上周周一
        Date upperSunday = upperGetweek[1];//上周周末
        Date monthStartDate = dateRange[0];//本月第一天
        Date monthEndDate = dateRange[1];//本月最后一天
        Date yearStartDate = yearDateRange[0];//本年第一天
        Date yearEndDate = yearDateRange[1];//本年最后一天
        Date upperYearStartDate = upperYearDateRange[0];//去年第一天

        Date[] upperYearWeek = DateUtils.getweek(0, upperYearSunday);//上年周
        Date[] upperYeardateRange = DateUtils.getDateRange(Integer.valueOf(lastMonth[1]) - 1, Integer.valueOf(lastMonth[2]));
        Date upperYearMon = upperYearWeek[0];//上年周周一
        Date upperYearSun = upperYearWeek[1];//上年周周末
        int upperYearDay = DateUtils.getDaysOfMonth(getweek[0]);//上年周所在月天数
        Date upperYearmonthStartDate = upperYeardateRange[0];//上年本月第一天
        Date upperYearmonthEndDate = upperYeardateRange[1];//上年本月最后一天

        System.out.println(day + "月天数");
        System.out.println(differ + "开始时间与结束时间相差天数");
        System.out.println(currentDays + "当前是本月的第几天");
        System.out.println(sdf.format(currentMonday) + "当前周周一");
        System.out.println(sdf.format(currentSunday) + "当前周周末");
        System.out.println(sdf.format(upperYearMonday) + "当前周周一减一年 去年的时间");
        System.out.println(sdf.format(upperYearSunday) + "当前周周末减一年  去年的时间");
        System.out.println(sdf.format(upperMonday) + "上周周一");
        System.out.println(sdf.format(upperSunday) + "上周周末");
        System.out.println(sdf.format(monthStartDate) + "本月第一天");
        System.out.println(sdf.format(monthEndDate) + "本月最后一天");
        System.out.println(sdf.format(yearStartDate) + "本年第一天");
        System.out.println(sdf.format(yearEndDate) + "本年最后一天");
        System.out.println(sdf.format(upperYearStartDate) + "去年第一天");
        System.out.println(upperEndDate + "上月最后一天");
        System.out.println(currentDays + "本月第几天");
        System.out.println(upperYearDay + "上年周所在月天数");
        System.out.println(upperYearmonthStartDate + "上年本月第一天");
        System.out.println(upperYearmonthEndDate + "上年本月最后一天");
        //计划  根据时间查询月计划除天数
        //本周所在月计划
        StatisticalWeekVo vo = statisticMapper.planSaleOfMonths(monthStartDate, monthEndDate, mineCode);

        //本周所在年计划
        StatisticalWeekVo yearVo = statisticMapper.planSaleOfYears(monthStartDate, monthEndDate, mineCode);
        //本周执行
        ExecutionSaleVo executionSaleVo = statisticMapper.ExecutionSale(currentMonday, currentSunday, mineCode);
        //本周去年同期
        ExecutionSaleVo upperYearExecutionSaleVo = statisticMapper.ExecutionSale(upperYearMon, upperYearSun, mineCode);
        //上周
        ExecutionSaleVo upperWeekExecutionSaleVo = statisticMapper.ExecutionSale(upperMonday, upperSunday, mineCode);
        //本月执行
        ExecutionSaleVo monthExecutionSaleVo = statisticMapper.ExecutionSale(monthStartDate, monthEndDate, mineCode);
        //本年执行
        ExecutionSaleVo yearExecutionSaleVo = statisticMapper.ExecutionSale(yearStartDate, yearEndDate, mineCode);
        //去年执行
        ExecutionSaleVo upperyearExecutionSaleVo = statisticMapper.ExecutionSale(upperYearStartDate, upperYearSunday, mineCode);

        if (vo != null) {
            //本周计划= 月计划/天数 * 7
            vo.setWeekPlan(String.valueOf(new BigDecimal(vo.getMonthPlan()).divide(new BigDecimal(day), 2, BigDecimal.ROUND_CEILING).multiply(new BigDecimal(differ))));
        } else {
            vo = new StatisticalWeekVo();
        }
        vo.setUnit("高头窑煤矿");
        if (executionSaleVo != null) {
            //本周执行
            vo.setCurrentWeek(String.valueOf(executionSaleVo.getSalesVolume().compareTo(BigDecimal.ZERO) == 0 ? "--" : executionSaleVo.getSalesVolume()));
        }
        if (upperYearExecutionSaleVo != null) {
            //本周去年同期
            vo.setWeekYearSame(String.valueOf(upperYearExecutionSaleVo.getSalesVolume().compareTo(BigDecimal.ZERO) == 0 ? "--" : upperYearExecutionSaleVo.getSalesVolume()));
        }
        //本周同比增减量 = 本周执行-本周去年同期
        vo.setWeekAddSubtractMeasure(vo.getCurrentWeek().equals("--") ? "--" : String.valueOf(new BigDecimal(vo.getCurrentWeek()).subtract(new BigDecimal(vo.getWeekYearSame().equals("--") ? "0" : vo.getWeekYearSame()))));
        //本周同比增减百分比 = "同比增减量" /  本周去年同期
        vo.setWeekAddSubtractPercentage(vo.getWeekAddSubtractMeasure().equals("--") || vo.getWeekYearSame().equals("--") ? "--" : new BigDecimal(vo.getWeekAddSubtractMeasure()).
                divide(new BigDecimal(vo.getWeekYearSame().equals("--") ? "0" : vo.getWeekYearSame()), 2, BigDecimal.ROUND_CEILING).multiply(new BigDecimal("100")) + "%");
        if (upperWeekExecutionSaleVo != null) {
            //上周执行
            vo.setUpperWeek(String.valueOf(upperWeekExecutionSaleVo.getSalesVolume().compareTo(BigDecimal.ZERO) == 0 ? "--" : upperWeekExecutionSaleVo.getSalesVolume()));
        }
        //环比增减量  本周 - 上周
        vo.setRatioAddSubtractMeasure(vo.getCurrentWeek().equals("--") ? "--" : String.valueOf(new BigDecimal(vo.getCurrentWeek()).subtract(new BigDecimal(vo.getUpperWeek().equals("--") ? "0" : vo.getUpperWeek()))));
        //环比增减百分比 环比增减量 / 上周
        vo.setRatioAddSubtractPercentage(vo.getRatioAddSubtractMeasure().equals("--") || vo.getUpperWeek().equals("--") ? "--" :
                new BigDecimal(vo.getRatioAddSubtractMeasure()).divide(new BigDecimal(vo.getUpperWeek().equals("--") ? "0"
                        : vo.getUpperWeek()), 2, BigDecimal.ROUND_CEILING).multiply(new BigDecimal("100")) + "%");
        //日均 = 本周执行 / 相差天数
        vo.setSunAverage(vo.getCurrentWeek().equals("--") ? "--" : new BigDecimal(vo.getCurrentWeek()).divide(new BigDecimal(differ), 2, BigDecimal.ROUND_CEILING) + "");
        if (monthExecutionSaleVo != null) {
            //本月执行
            vo.setCurrentMonthAccomplish(monthExecutionSaleVo.getSalesVolume().compareTo(BigDecimal.ZERO) == 0 ? "--" : monthExecutionSaleVo.getSalesVolume() + "");
        }
        //完成月计划百分比 = 本月执行 /  本月计划
        vo.setAccomplishPlanPercentage(monthExecutionSaleVo.getSalesVolume().compareTo(BigDecimal.ZERO) == 0 || vo.getMonthPlan().equals("0") ? "--" :
                monthExecutionSaleVo.getSalesVolume().divide(new BigDecimal(vo.getMonthPlan()), 2, BigDecimal.ROUND_CEILING) + "");
        //年度计划
        vo.setYearPlan(yearVo.getMonthPlan().equals("0") ? "--" : yearVo.getMonthPlan());

        // 进度计划  = 当前月之前的月计划相加 + 本月的计划 / 月天数 * 当前是本月的第几天
        Calendar calendar = Calendar.getInstance();
        int month = calendar.get(Calendar.MONTH) + 1;
        StatisticalWeekVo monthVo = null;
        if (lastMonth[2].equals("1") && month == 1) {
            //如果是一月，直接拿计划 / 月天数  * 当前天数
            monthVo = statisticMapper.planSaleOfMonths(yearStartDate, currentSunday, mineCode);
        } else {
            //不是一月，算开年到上月低的计划总和  + （本月计划  /  月天数 * 当前天数）
            //截至到当前月上月得计划
            monthVo = statisticMapper.planSaleOfMonths(yearStartDate, upperEndDate, mineCode);

        }
        if (monthVo != null) {
            vo.setRatePlan(new BigDecimal(monthVo.getMonthPlan()).add(new BigDecimal(vo.getMonthPlan())) + "");
        }

        //本年执行
        if (yearExecutionSaleVo != null) {
            vo.setCurrentYearAccomplish(yearExecutionSaleVo.getSalesVolume().compareTo(BigDecimal.ZERO) == 0 ? "--" : yearExecutionSaleVo.getSalesVolume() + "");
        }
        //完成年计划百分比 = 本年完成 / 年度计划
        vo.setPlanAccomplishPercentage(yearExecutionSaleVo.getSalesVolume().compareTo(BigDecimal.ZERO) == 0 || yearVo.getMonthPlan().equals("0") ? "--" : yearExecutionSaleVo.getSalesVolume().
                divide(new BigDecimal(yearVo.getMonthPlan()), 2, BigDecimal.ROUND_CEILING).multiply(new BigDecimal("100")) + "%");
        //超欠 = 本年完成 - 进度计划
        vo.setBackBreak(vo.getCurrentYearAccomplish().equals("--") ? "--" : new BigDecimal(vo.getCurrentYearAccomplish()).subtract(new BigDecimal(vo.getRatePlan())) + "");
        //超欠百分比 = 超欠 / 进度计划
        vo.setBackBreakPercentage(vo.getBackBreak().equals("--") ? "--" : new BigDecimal(vo.getBackBreak()).divide(new BigDecimal(vo.getRatePlan().equals("0") ? "1" : vo.getRatePlan()), 2, BigDecimal.ROUND_CEILING) + "");
        //去年同期
        if (upperyearExecutionSaleVo != null) {
            vo.setCurrentYearSame(upperyearExecutionSaleVo.getSalesVolume() + "");
        }
        //年同比增减量 = 本年执行 - 去年同期
        vo.setYearAddSubtractMeasure(yearExecutionSaleVo.getSalesVolume().subtract(upperyearExecutionSaleVo.getSalesVolume()) + "");
        //同比增减百分比 = 同比增减量 / 去年同期
        vo.setYearAddSubtractPercentage(vo.getYearAddSubtractMeasure().equals("0") || upperyearExecutionSaleVo.getSalesVolume().compareTo(BigDecimal.ZERO) == 0 ? "--" :
                new BigDecimal(vo.getYearAddSubtractMeasure()).divide(upperyearExecutionSaleVo.getSalesVolume(), 2, BigDecimal.ROUND_CEILING).multiply(new BigDecimal("100")) + "%");

        return vo;
    }

    @Override
    public List<MonthValue> achievementsLastSixMonths(String companyCode) {
        List<MonthValue> monthValues = statisticMapper.achievementsLastSixMonths(companyCode);
        return monthValues;
    }

    @Override
    public List<MonthValue> gtySalePlanLastSixMonths(String companyCode) {
        List<MonthValue> monthValues = statisticMapper.gtySalePlanLastSixMonths(companyCode);
        return monthValues;
    }

    @Override
    public void importExcel(MultipartFile file, IntegratedReportingMapper integratedReportingMapper) {

        String sufix = StrUtil.subAfter(file.getOriginalFilename(), ".", true);
        if (!"xls".equals(sufix) && !"xlsx".equals(sufix))
            throw new HuaNengException(Constants.FAIL, "文件格式仅支持xls或xlsx");

        try {
            EasyExcel.read(file.getInputStream(), IntegratedReporting.class, new IntegratedReportingListener(integratedReportingMapper)).sheet().doRead();
        } catch (IOException e) {
            throw new HuaNengException(Constants.FAIL, "内容格式错误！");
        }

    }


    @Override
    public ResponsePage<IntegratedReporting> getIntegratedReporting(String date, String name, PageQuery pageQuery) {
        LambdaQueryWrapper<IntegratedReporting> lambdaQueryWrapper = new LambdaQueryWrapper();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date param = null;
        try {
            if (StrUtil.isNotBlank(date)) {
                param = dateFormat.parse(date);
            }

        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        lambdaQueryWrapper.eq(StrUtil.isNotBlank(date), IntegratedReporting::getDate, param) // 添加自定义SQL语句
                .like(StrUtil.isNotBlank(name), IntegratedReporting::getName, name)   // 使用占位符设置参数值
                .select(IntegratedReporting::getDate, IntegratedReporting::getDayPeel, IntegratedReporting::getDayYield,
                        IntegratedReporting::getDaySale, IntegratedReporting::getMonthPeel, IntegratedReporting::getMonthSale,
                        IntegratedReporting::getMonthYield, IntegratedReporting::getName, IntegratedReporting::getType,
                        IntegratedReporting::getSaleBazaarCoal, IntegratedReporting::getSaleNorthInterior, IntegratedReporting::getSaleGroupInterior, IntegratedReporting::getSalePowerPlant)
                .orderByDesc(IntegratedReporting::getDate);


        Page<IntegratedReporting> page = integratedReportingMapper.selectPage(pageQuery.build(), lambdaQueryWrapper);

        ResponsePage responsePage = new ResponsePage(page.getRecords(), page.getTotal());
        return responsePage;

    }

    @Override
    public List<IntegratedReporting> getYieldSaleStatistics() {
        return integratedReportingMapper.getYieldSaleStatistics();
    }

    @Override
    public List<IntegratedReporting> getDayYieldSaleStatistics(int month) {
        List<IntegratedReporting> list = integratedReportingMapper.getDayYieldSaleStatistics(month);

        return formatDates(list);
    }

    public static List<IntegratedReporting> formatDates(List<IntegratedReporting> dates) {
        List<IntegratedReporting> formattedDates = new ArrayList<>();

        SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat outputFormat = new SimpleDateFormat("d");

        for (IntegratedReporting dateStr : dates) {
            try {
                Date date = inputFormat.parse(dateStr.getDateStatistics());
                String formattedDate = outputFormat.format(date);
                dateStr.setDateStatistics(formattedDate);
                formattedDates.add(dateStr);
            } catch (ParseException e) {
                // 处理解析错误
                e.printStackTrace();
            }
        }

        return formattedDates;
    }


    @Override
    public List<YearEnergyStatisticsVo> getYearOutputCurve(String mineCode, Integer year) {
        YearEnergyStatisticsVo output = new YearEnergyStatisticsVo("output");
        YearEnergyStatisticsVo electrical = new YearEnergyStatisticsVo("electrical");
        YearEnergyStatisticsVo water = new YearEnergyStatisticsVo("water");
        // 产量
        // year  实际
        List<YearEnergyStatisticsVo> yearEnergyStatistics = statisticMapper.getYearOutput(mineCode, year + "", (year - 1) + "");
        if (CollectionUtil.isEmpty(yearEnergyStatistics)) {
            output.setYearData("0.0");
            output.setLastYearData("0.0");
        } else {
            Optional<YearEnergyStatisticsVo> first = yearEnergyStatistics.stream().filter(u -> StringUtils.equals(u.getYear(), year + "")).findFirst();
            output.setYearData(first.isPresent() ? first.get().getYearData() : "0.0");
            Optional<YearEnergyStatisticsVo> lastYear = yearEnergyStatistics.stream().filter(u -> StringUtils.equals(u.getYear(), (year - 1) + "")).findFirst();
            output.setLastYearData(lastYear.isPresent() ? lastYear.get().getYearData() : "0.0");
        }
        // year 计划
        YearEnergyStatisticsVo yearPlan = statisticMapper.yearPlanOutput(mineCode, year + "");
        if (yearPlan == null) {
            output.setPlan("0.0");
        } else {
            output.setPlan(yearPlan.getYearData());
        }
        output.setSameYearData(StatisticsUtil.calculateGrowthRate(output.getYearData(), output.getLastYearData()));
        output.setPlanCompletion(StatisticsUtil.calculateCompletionRate(output.getYearData(), output.getPlan()));

        //水+电
        Date[] dateRange = DateUtils.getDateRangeUtilNow(year, null);
        DynamicDataSourceContextHolder.push("energy");
        List<MonthValue> costOfMonth = statisticMapper.sumEnergyCost(dateRange[0], dateRange[1], mineCode);
        Map<String, Date[]> stringMap = DateUtils.calculateComparisonDateRange(year);
        Date date = stringMap.get("yearOnYear")[0];
        Date date1 = stringMap.get("yearOnYear")[1];
        List<MonthValue> lastCostOfMonth = statisticMapper.sumEnergyCost(date, date1, mineCode);
        DynamicDataSourceContextHolder.clear();
        if (CollectionUtil.isEmpty(costOfMonth)) {
            electrical.setYearData("0.0");
            water.setYearData("0.0");
        } else {
            double electricalSum = costOfMonth.stream().mapToDouble(u -> u.getTotal3().doubleValue()).sum();
            electrical.setYearData(StatisticsUtil.calculateRatio(String.valueOf(electricalSum), output.getYearData()));
            double waterSum = costOfMonth.stream().mapToDouble(u -> u.getTotal1().doubleValue()).sum();
            water.setYearData(StatisticsUtil.calculateRatio(String.valueOf(waterSum), output.getYearData()));
        }
        if (CollectionUtil.isEmpty(lastCostOfMonth)) {
            electrical.setLastYearData("0.0");
            water.setLastYearData("0.0");
        } else {
            double electricalSum = lastCostOfMonth.stream().mapToDouble(u -> u.getTotal3().doubleValue()).sum();
            electrical.setLastYearData(StatisticsUtil.calculateRatio(String.valueOf(electricalSum), output.getLastYearData()));
            double waterSum = lastCostOfMonth.stream().mapToDouble(u -> u.getTotal1().doubleValue()).sum();
            water.setLastYearData(StatisticsUtil.calculateRatio(String.valueOf(waterSum), output.getLastYearData()));
        }
        electrical.setSameYearData(StatisticsUtil.calculateGrowthRate(electrical.getYearData(), electrical.getLastYearData()));
        electrical.setPlan(output.getPlan());
        electrical.setPlanCompletion(output.getPlanCompletion());
        water.setSameYearData(StatisticsUtil.calculateGrowthRate(water.getYearData(), water.getLastYearData()));
        water.setPlan(output.getPlan());
        water.setPlanCompletion(output.getPlanCompletion());
        return Arrays.asList(output, electrical, water);
    }

    @Override
    public List<MonthValue> getYearOutputEnergyCurve(String mineCode, Integer year) {
        Date[] dateRange = DateUtils.getDateRangeUtilNow(year, null);
        List<MonthValue> result = new ArrayList<>();
        List<MonthValue> monthValueList = statisticMapper.sumPlanOutputAndRealOutput(dateRange[0], dateRange[1], mineCode);

        DynamicDataSourceContextHolder.push("energy");
        Map<Integer, MonthValue> energyMap = statisticMapper.sumEnergyCost(dateRange[0], dateRange[1], mineCode)
                .stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));
        DynamicDataSourceContextHolder.clear();

        for (int i = 1; i < DateUtil.month(dateRange[1]) + 2; i++) {
            int finalI = i;
            MonthValue monthValue = monthValueList.stream().filter(o -> o.getMonth() != null && o.getMonth() == finalI).findFirst().orElse(new MonthValue(finalI));
            MonthValue energy = energyMap.getOrDefault(i, new MonthValue(i));
            energy.setTotal4(monthValue.getTotal2());
            result.add(energy);
        }
        return result;
    }

    @Override
    public List<MonthValue> getElectricityAndOutput(Integer year, String mineCode) {
        List<MonthValue> result = new ArrayList<>();
        Date[] dateRange = DateUtils.getDateRangeUtilNow(year, null);
        Map<String, Date[]> stringMap = DateUtils.calculateComparisonDateRange(year);
        Map<Integer, MonthValue> currentDateRange = statisticMapper.sumPlanOutputAndRealOutput(dateRange[0], dateRange[1], mineCode)
                .stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));
        Map<Integer, MonthValue> lastDateRange = statisticMapper.sumPlanOutputAndRealOutput(stringMap.get("yearOnYear")[0], stringMap.get("yearOnYear")[1], mineCode)
                .stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));
        DynamicDataSourceContextHolder.push("energy");
        Map<Integer, MonthValue> curEnergyMap = statisticMapper.sumEnergyCost(dateRange[0], dateRange[1], mineCode)
                .stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));
        Map<Integer, MonthValue> lastEnergyMap = statisticMapper.sumEnergyCost(stringMap.get("yearOnYear")[0], stringMap.get("yearOnYear")[1], mineCode)
                .stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));
        DynamicDataSourceContextHolder.clear();
        for (int i = 1; i < DateUtil.month(dateRange[1]) + 2; i++) {
            MonthValue item = new MonthValue(i);
            // 产量同比
            item.setTotal(new BigDecimal(StatisticsUtil.calculateGrowthRate(currentDateRange.getOrDefault(i, new MonthValue(i)).getTotal2().toPlainString(), lastDateRange.getOrDefault(i, new MonthValue(i)).getTotal2().toPlainString())));
            // 产量环比
            if (i == 1) {
                item.setTotal1(new BigDecimal(StatisticsUtil.calculateMoMGrowthRate(currentDateRange.getOrDefault(i, new MonthValue(i)).getTotal().toPlainString(), lastDateRange.getOrDefault(12, new MonthValue(12)).getTotal().toPlainString())));
            } else {
                item.setTotal1(new BigDecimal(StatisticsUtil.calculateMoMGrowthRate(currentDateRange.getOrDefault(i, new MonthValue(i)).getTotal().toPlainString(), currentDateRange.getOrDefault(i - 1, new MonthValue(i - 1)).getTotal().toPlainString())));
            }
            // 电同比
            item.setTotal3(new BigDecimal(StatisticsUtil.calculateGrowthRate(curEnergyMap.getOrDefault(i, new MonthValue(i)).getTotal3().toPlainString(), lastEnergyMap.getOrDefault(i, new MonthValue(i)).getTotal3().toPlainString())));
            // 电环比
            if (i == 1) {
                item.setTotal4(new BigDecimal(StatisticsUtil.calculateMoMGrowthRate(curEnergyMap.getOrDefault(i, new MonthValue(i)).getTotal3().toPlainString(), lastEnergyMap.getOrDefault(12, new MonthValue(12)).getTotal3().toPlainString())));
            } else {
                item.setTotal4(new BigDecimal(StatisticsUtil.calculateMoMGrowthRate(curEnergyMap.getOrDefault(i, new MonthValue(i)).getTotal3().toPlainString(), curEnergyMap.getOrDefault(i - 1, new MonthValue(i - 1)).getTotal3().toPlainString())));
            }
            // 水同比
            item.setTotal5(new BigDecimal(StatisticsUtil.calculateGrowthRate(curEnergyMap.getOrDefault(i, new MonthValue(i)).getTotal1().toPlainString(), lastEnergyMap.getOrDefault(i, new MonthValue(i)).getTotal1().toPlainString())));
            // 水环比
            if (i == 1) {
                item.setTotal6(new BigDecimal(StatisticsUtil.calculateMoMGrowthRate(curEnergyMap.getOrDefault(i, new MonthValue(i)).getTotal1().toString(), lastEnergyMap.getOrDefault(12, new MonthValue(12)).getTotal1().toString())));
            } else {
                item.setTotal6(new BigDecimal(StatisticsUtil.calculateMoMGrowthRate(curEnergyMap.getOrDefault(i, new MonthValue(i)).getTotal1().toString(), curEnergyMap.getOrDefault(i - 1, new MonthValue(i - 1)).getTotal1().toString())));
            }
            result.add(item);
        }
        return result;
    }

    @Override
    public List<OtherMonthCostVo> otherMonthCost(String searchDate, String mineCode) {
        OtherMonthCostVo otherMonthCost1 = new OtherMonthCostVo("1");
        OtherMonthCostVo otherMonthCost2 = new OtherMonthCostVo("2");
        OtherMonthCostVo otherMonthCost3 = new OtherMonthCostVo("3");
        OtherMonthCostVo otherMonthCost4 = new OtherMonthCostVo("4");
        OtherMonthCostVo otherMonthCost5 = new OtherMonthCostVo("5");
        Date date = DateUtils.parseDate(searchDate);
        String[] daySplit = searchDate.split("-");
        Date[] dateRange = DateUtils.getDateRangeUtilNow(Integer.parseInt(daySplit[0]), null);
        int month = Integer.parseInt(daySplit[0]);
        Map<Integer, MonthValue> costList = statisticMapper.sumCost(dateRange[0], dateRange[1], mineCode)
                .stream().collect(Collectors.toMap(MonthValue::getMonth, Function.identity()));
        MonthValue currentMonth = costList.getOrDefault(month, new MonthValue(month));
        if (!costList.isEmpty()) {
            otherMonthCost1.setMonthCost(currentMonth.getTotal() + "");
            otherMonthCost2.setMonthCost(currentMonth.getTotal2() + "");
            otherMonthCost3.setMonthCost(currentMonth.getTotal3() + "");
            otherMonthCost1.setYearCost(costList.values().stream().mapToDouble(u -> u.getTotal().doubleValue()).sum() + "");
            otherMonthCost2.setYearCost(costList.values().stream().mapToDouble(u -> u.getTotal2().doubleValue()).sum() + "");
            otherMonthCost3.setYearCost(costList.values().stream().mapToDouble(u -> u.getTotal3().doubleValue()).sum() + "");
        }
        //南风井、副井
        DynamicDataSourceContextHolder.push("energy");
        List<MonthValue> monthValues = statisticMapper.sumPlaceEnergyCost(dateRange[0], dateRange[1], mineCode);
        DynamicDataSourceContextHolder.clear();
        if (CollectionUtils.isNotEmpty(monthValues)) {
            List<MonthValue> p1 = monthValues.stream().filter(u -> u.getName().contains("南风井")).collect(Collectors.toList());
            List<MonthValue> p2 = monthValues.stream().filter(u -> u.getName().contains("副井")).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(p1)) {
                double sum = p1.stream().filter(u -> u.getMonth() == month).mapToDouble(u -> u.getTotal().doubleValue()).sum();
                otherMonthCost4.setMonthCost(sum + "");
                otherMonthCost4.setYearCost(p1.stream().mapToDouble(u -> u.getTotal().doubleValue()).sum() + "");
            }
            if (CollectionUtils.isNotEmpty(p2)) {
                double sum = p2.stream().filter(u -> u.getMonth() == month).mapToDouble(u -> u.getTotal().doubleValue()).sum();
                otherMonthCost5.setMonthCost(sum + "");
                otherMonthCost5.setYearCost(p2.stream().mapToDouble(u -> u.getTotal().doubleValue()).sum() + "");
            }
        }
        return Arrays.asList(otherMonthCost1, otherMonthCost2, otherMonthCost3, otherMonthCost4, otherMonthCost5);
    }

    @Override
    public List<MonthValue> getProductionWaterSupply(Integer year, String mineCode) {
        List<MonthValue> result = new ArrayList<>();
        Date[] dateRange = DateUtils.getDateRangeUtilNow(year, null);
        DynamicDataSourceContextHolder.push("energy");
        List<MonthValue> monthValues = statisticMapper.sumPlaceEnergyCost(dateRange[0], dateRange[1], mineCode);
        DynamicDataSourceContextHolder.clear();
        for (int i = 1; i < DateUtil.month(dateRange[1]) + 2; i++) {
            MonthValue item = new MonthValue(i);
            if (CollectionUtils.isNotEmpty(monthValues)) {
                int finalI = i;
                double sum1 = monthValues.stream().filter(u -> u.getMonth() == finalI && u.getName().contains("南风井")).mapToDouble(u -> u.getTotal().doubleValue()).sum();
                item.setTotal(new BigDecimal(sum1));
                double sum2 = monthValues.stream().filter(u -> u.getMonth() == finalI && u.getName().contains("副井")).mapToDouble(u -> u.getTotal().doubleValue()).sum();
                item.setTotal1(new BigDecimal(sum2));
            }
            result.add(item);
        }
        return result;
    }


}
